double CSketch::GetArea()const { double area = 0.0; for(std::list<HeeksObj*>::const_iterator It=m_objects.begin(); It!=m_objects.end() ;It++) { HeeksObj* object = *It; switch(object->GetType()) { case ArcType: { double angle = ((HArc*)object)->IncludedAngle(); double radius = ((HArc*)object)->m_radius; double p0x = ((HArc*)object)->A->m_p.X(); double p0y = ((HArc*)object)->A->m_p.Y(); double p1x = ((HArc*)object)->B->m_p.X(); double p1y = ((HArc*)object)->B->m_p.Y(); double pcx = ((HArc*)object)->C->m_p.X(); double pcy = ((HArc*)object)->C->m_p.Y(); area += ( 0.5 * ((pcx - p0x) * (pcy + p0y) - (pcx - p1x) * (pcy + p1y) - angle * radius * radius)); } break; default: // treat all others as lines { double s[3], e[3]; if(!object->GetStartPoint(s))break; if(!object->GetEndPoint(e))break; area += (0.5 * (e[0] - s[0]) * (s[1] + e[1])); } break; } } return area; }
bool Excellon::Read( const char *p_szFileName, const bool force_mirror /* = false */ ) { printf("Excellon::Read(%s)\n", p_szFileName ); if (force_mirror) { m_mirror_image_x_axis = true; } // First read in existing PointType object locations so that we don't duplicate points. for (HeeksObj *obj = heeksCAD->GetFirstObject(); obj != NULL; obj = heeksCAD->GetNextObject() ) { if (obj->GetType() != PointType) continue; double pos[3]; obj->GetStartPoint( pos ); m_existing_points.insert( std::make_pair( CNCPoint( pos ), CDrilling::Symbol_t( PointType, obj->m_id ) ) ); } // End for std::ifstream input( p_szFileName, std::ios::in ); if (input.is_open()) { m_current_line = 0; while (input.good()) { char memblock[512]; memset( memblock, '\0', sizeof(memblock) ); input.getline( memblock, sizeof(memblock)-1 ); if (memblock[0] != '\0') { if (! ReadDataBlock( memblock )) return(false); } // End if - then } // End while // Now go through and add the drilling cycles for each different tool. std::set< CTool::ToolNumber_t > tool_numbers; for (Holes_t::const_iterator l_itHole = m_holes.begin(); l_itHole != m_holes.end(); l_itHole++) { tool_numbers.insert( l_itHole->first ); } // End for for (std::set<CTool::ToolNumber_t>::const_iterator l_itToolNumber = tool_numbers.begin(); l_itToolNumber != tool_numbers.end(); l_itToolNumber++) { double depth = 2.5; // mm CDrilling *new_object = new CDrilling( m_holes[ *l_itToolNumber ], *l_itToolNumber, depth ); new_object->m_speed_op_params.m_spindle_speed = m_spindle_speed; new_object->m_speed_op_params.m_vertical_feed_rate = m_feed_rate; new_object->m_params.m_peck_depth = 0.0; // Don't peck for a Printed Circuit Board. new_object->m_params.m_dwell = 0.0; // Don't wait around to clear stringers either. new_object->m_params.m_standoff = 2.0; // Printed Circuit Boards a quite flat theApp.m_program->Operations()->Add(new_object,NULL); } // End for return(true); // Success } // End if - then else { // Couldn't read file. printf("Could not open '%s' for reading\n", p_szFileName ); return(false); } // End if - else } // End Read() method
/** * If the tool_number is positive and relates to an existing * Tool object then take the toolcornerrad and toolflatrad * from the Tool object's values. * * If the reference_object_type/id refers to either a point object * or a Drilling object then use that object's location as this * operation's starting point. If they're negative or zero then * use the existing default values. * * Also check the heights of the solids and set the retractzheight * parameter accordingly. */ void CAdaptiveParams::set_initial_values( const std::list<int> &solids, const int tool_number /* = 0 */, const int reference_object_type, /* = -1 */ const unsigned int reference_object_id, /* = -1 */ const std::list<int> &sketches ) { CNCConfig config(ConfigScope()); config.Read(_T("m_leadoffdz"), &m_leadoffdz, 0.1); config.Read(_T("m_leadofflen"), &m_leadofflen, 1.1); config.Read(_T("m_leadoffrad"), &m_leadoffrad, 2.0); config.Read(_T("m_retractzheight"), &m_retractzheight, 20.0); config.Read(_T("m_leadoffsamplestep"), &m_leadoffsamplestep, 0.6); config.Read(_T("m_toolcornerrad"), &m_toolcornerrad, 3.0); config.Read(_T("m_toolflatrad"), &m_toolflatrad, 0.0); config.Read(_T("m_samplestep"), &m_samplestep, 0.4); config.Read(_T("m_stepdown"), &m_stepdown, 5.0); config.Read(_T("m_clearcuspheight"), &m_clearcuspheight, m_stepdown / 3.0); config.Read(_T("m_triangleweaveres"), &m_triangleweaveres, 0.51); config.Read(_T("m_flatradweaveres"), &m_flatradweaveres, 0.71); config.Read(_T("m_dchangright"), &m_dchangright, 0.17); config.Read(_T("m_dchangrightoncontour"), &m_dchangrightoncontour, 0.37); config.Read(_T("m_dchangleft"), &m_dchangleft, -0.41); config.Read(_T("m_dchangefreespace"), &m_dchangefreespace, -0.6); config.Read(_T("m_sidecutdisplch"), &m_sidecutdisplch, 0.3); config.Read(_T("m_fcut"), &m_fcut, 1000); config.Read(_T("m_fretract"), &m_fretract, 5000); config.Read(_T("m_thintol"), &m_thintol, 0.0001); config.Read(_T("m_startpoint_x"), &m_startpoint_x, 0); config.Read(_T("m_startpoint_y"), &m_startpoint_y, 0); config.Read(_T("m_startvel_x"), &m_startvel_x, 1); config.Read(_T("m_startvel_y"), &m_startvel_y, 1); config.Read(_T("m_minz"), &m_minz, -10000000.0); config.Read(_T("m_boundaryclear"), &m_boundaryclear, 21); config.Read(_T("m_boundary_x0"), &m_boundary_x0, -20); config.Read(_T("m_boundary_x1"), &m_boundary_x1, 20); config.Read(_T("m_boundary_y0"), &m_boundary_y0, -20); config.Read(_T("m_boundary_y1"), &m_boundary_y1, 20); // If the user has selected a tool as part of this operation then use that tool's // parameters to set these ones. If no tool was selected then it's back to default // behaviour for this module. if ((tool_number > 0) && (CTool::FindTool( tool_number ) > 0)) { CTool *pTool = (CTool *) CTool::Find( tool_number ); if (pTool != NULL) { m_toolcornerrad = pTool->m_params.m_corner_radius; m_toolflatrad = pTool->m_params.m_flat_radius; m_stepdown = pTool->m_params.m_cutting_edge_height / 4.0; m_clearcuspheight = m_stepdown / 3.0; } // End if - then } // End if - then // The operator has selected a reference object. We can use that object // to determine the starting point for this operation. The user can always // override this point by updating the properties later on. if ((reference_object_type > 0) && (reference_object_id > 0)) { HeeksObj *ref = heeksCAD->GetIDObject( reference_object_type, reference_object_id ); if (ref != NULL) { double start[3] = {0.0, 0.0, 0.0}; switch (reference_object_type) { case PointType: if (ref->GetStartPoint( start )) { m_startpoint_x = start[0]; m_startpoint_y = start[1]; } // End if - then break; case DrillingType: { std::vector<CNCPoint> locations; locations = CDrilling::FindAllLocations((CDrilling *)ref); if (locations.size() == 1) { // There must be only one (didn't someone else say that once?) for our purposes. m_startpoint_x = locations.begin()->X(); m_startpoint_y = locations.begin()->Y(); } // End if - then } // End DrillingType scope break; default: // We only support a couple of types. break; } // End switch } // End if - then } // End if - then // Look through the solids that make up the model and find a safe height. double max_z = CAdaptive::GetMaxHeight( SolidType, solids ); if (m_retractzheight < max_z) m_retractzheight = max_z; // Look at the sketches that make up the boundary and set the boundaryclear value to the // highest Z value. max_z = CAdaptive::GetMaxHeight( SketchType, sketches ); if (m_boundaryclear < max_z) m_boundaryclear = max_z; }
void CSketch::CalculateSketchOrder() { if(m_objects.size() == 0) { m_order = SketchOrderTypeEmpty; return; } HeeksObj* prev_object = NULL; HeeksObj* first_object = NULL; bool well_ordered = true; std::list<HeeksObj*>::iterator It; for(It=m_objects.begin(); It!=m_objects.end() ;It++) { HeeksObj* object = *It; if(object->GetType() == CircleType) { m_order = SketchOrderHasCircles; return; } if(prev_object) { double prev_e[3], s[3]; if(!prev_object->GetEndPoint(prev_e)){well_ordered = false; break;} if(!object->GetStartPoint(s)){well_ordered = false; break;} if(!(make_point(prev_e).IsEqual(make_point(s), wxGetApp().m_geom_tol))){well_ordered = false; break;} } if(first_object == NULL)first_object = object; prev_object = object; } if(well_ordered) { if(prev_object && first_object) { double e[3], s[3]; if(prev_object->GetEndPoint(e)) { if(first_object->GetStartPoint(s)) { if(make_point(e).IsEqual(make_point(s), wxGetApp().m_geom_tol)) { // closed if(IsClockwise())m_order = SketchOrderTypeCloseCW; else m_order = SketchOrderTypeCloseCCW; return; } } } } m_order = SketchOrderTypeOpen; return; } m_order = SketchOrderTypeBad; // although it might still be multiple, but will have to wait until ReOrderSketch is done. }
/** * 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