/** * This method looks through the symbols in the list. If they're PointType objects * then the object's location is added to the result set. If it's a circle object * that doesn't intersect any other element (selected) then add its centre to * the result set. Finally, find the intersections of all of these elements and * add the intersection points to the result vector. */ /* static */ std::vector<CNCPoint> CDrilling::FindAllLocations( ObjList *parent, const CNCPoint starting_location, // = CNCPoint(0.0, 0.0, 0.0) const bool sort_locations, // = false std::list<int> *pToolNumbersReferenced /* = NULL */ ) { std::vector<CNCPoint> locations; parent->ReloadPointers(); // Make sure our integer lists have been converted into children first. // Look to find all intersections between all selected objects. At all these locations, create // a drilling cycle. std::list<HeeksObj *> lhs_children; std::list<HeeksObj *> rhs_children; for (HeeksObj *lhsPtr = parent->GetFirstChild(); lhsPtr != NULL; lhsPtr = parent->GetNextChild()) { lhs_children.push_back( lhsPtr ); rhs_children.push_back( lhsPtr ); } for (std::list<HeeksObj *>::iterator itLhs = lhs_children.begin(); itLhs != lhs_children.end(); itLhs++) { HeeksObj *lhsPtr = *itLhs; bool l_bIntersectionsFound = false; // If it's a circle and it doesn't // intersect anything else, we want to know // about it. if (lhsPtr->GetType() == PointType) { double pos[3]; lhsPtr->GetStartPoint(pos); // Copy the results in ONLY if each point doesn't already exist. if (std::find( locations.begin(), locations.end(), CNCPoint( pos ) ) == locations.end()) { locations.push_back( CNCPoint( pos ) ); } // End if - then continue; // No need to intersect a point with anything. } // End if - then for (std::list<HeeksObj *>::iterator itRhs = rhs_children.begin(); itRhs != rhs_children.end(); itRhs++) { HeeksObj *rhsPtr = *itRhs; if (lhsPtr == rhsPtr) continue; if (lhsPtr->GetType() == PointType) continue; // No need to intersect a point type. std::list<double> results; if ((lhsPtr != NULL) && (rhsPtr != NULL) && (lhsPtr->Intersects( rhsPtr, &results ))) { l_bIntersectionsFound = true; while (((results.size() % 3) == 0) && (results.size() > 0)) { CNCPoint intersection; intersection.SetX( *(results.begin()) ); results.erase(results.begin()); intersection.SetY( *(results.begin()) ); results.erase(results.begin()); intersection.SetZ( *(results.begin()) ); results.erase(results.begin()); // Copy the results in ONLY if each point doesn't already exist. if (std::find( locations.begin(), locations.end(), intersection ) == locations.end()) { locations.push_back(intersection); } // End if - then } // End while } // End if - then } // End for if (! l_bIntersectionsFound) { // This element didn't intersect anything else. If it's a circle // then add its centre point to the result set. if (lhsPtr->GetType() == CircleType) { double pos[3]; if ((lhsPtr != NULL) && (heeksCAD->GetArcCentre( lhsPtr, pos ))) { // Copy the results in ONLY if each point doesn't already exist. if (std::find( locations.begin(), locations.end(), CNCPoint( pos ) ) == locations.end()) { locations.push_back( CNCPoint( pos ) ); } // End if - then } // End if - then } // End if - then if (lhsPtr->GetType() == SketchType) { CBox bounding_box; lhsPtr->GetBox( bounding_box ); double pos[3]; bounding_box.Centre(pos); // Copy the results in ONLY if each point doesn't already exist. if (std::find( locations.begin(), locations.end(), CNCPoint( pos ) ) == locations.end()) { locations.push_back( CNCPoint( pos ) ); } // End if - then } // End if - then if (lhsPtr->GetType() == ProfileType) { std::vector<CNCPoint> starting_points; CMachineState machine; #ifndef STABLE_OPS_ONLY CFixture perfectly_aligned_fixture(NULL,CFixture::G54, false, 0.0); machine.Fixture(perfectly_aligned_fixture); #endif // to do, make this get the starting point again //((CProfile *)lhsPtr)->AppendTextToProgram( starting_points, &machine ); // Copy the results in ONLY if each point doesn't already exist. for (std::vector<CNCPoint>::const_iterator l_itPoint = starting_points.begin(); l_itPoint != starting_points.end(); l_itPoint++) { if (std::find( locations.begin(), locations.end(), *l_itPoint ) == locations.end()) { locations.push_back( *l_itPoint ); } // End if - then } // End for } // End if - then if (lhsPtr->GetType() == DrillingType) { // Ask the Drilling object what reference points it uses. if ((((COp *) lhsPtr)->m_tool_number > 0) && (pToolNumbersReferenced != NULL)) { pToolNumbersReferenced->push_back( ((COp *) lhsPtr)->m_tool_number ); } // End if - then std::vector<CNCPoint> holes = CDrilling::FindAllLocations((CDrilling *)lhsPtr, starting_location, false, pToolNumbersReferenced); for (std::vector<CNCPoint>::const_iterator l_itHole = holes.begin(); l_itHole != holes.end(); l_itHole++) { if (std::find( locations.begin(), locations.end(), *l_itHole ) == locations.end()) { locations.push_back( *l_itHole ); } // End if - then } // End for } // End if - then #ifndef STABLE_OPS_ONLY if (lhsPtr->GetType() == CounterBoreType) { std::vector<CNCPoint> holes = CDrilling::FindAllLocations((CCounterBore *)lhsPtr, starting_location, false, NULL); for (std::vector<CNCPoint>::const_iterator l_itHole = holes.begin(); l_itHole != holes.end(); l_itHole++) { if (std::find( locations.begin(), locations.end(), *l_itHole ) == locations.end()) { locations.push_back( *l_itHole ); } // End if - then } // End for } // End if - then #endif } // End if - then } // End for if (sort_locations) { // This drilling cycle has the 'sort' option turned on. // // If the sorting option is turned off then the points need to be returned in order of the m_symbols list. One day, // we will allow the operator to re-order the m_symbols list by using a drag-n-drop operation on the sub-elements // in the menu. When this is done, the operator's decision as to order should be respected. Until then, we can // use the 'sort' option in the drilling cycle's parameters. for (std::vector<CNCPoint>::iterator l_itPoint = locations.begin(); l_itPoint != locations.end(); l_itPoint++) { if (l_itPoint == locations.begin()) { // It's the first point. CNCPoint reference_location(0.0, 0.0, 0.0); reference_location = starting_location; sort_points_by_distance compare( reference_location ); std::sort( locations.begin(), locations.end(), compare ); } // End if - then else { // We've already begun. Just sort based on the previous point's location. std::vector<CNCPoint>::iterator l_itNextPoint = l_itPoint; l_itNextPoint++; if (l_itNextPoint != locations.end()) { sort_points_by_distance compare( *l_itPoint ); std::sort( l_itNextPoint, locations.end(), compare ); } // End if - then } // End if - else } // End for } // End if - then return(locations); } // End FindAllLocations() method