void HeeksDxfRead::AddGraphics() { // add one insert of any blocks which haven't been added at all m_current_block = NULL; for(Blocks_t::const_iterator It = m_blocks.begin(); It != m_blocks.end(); It++) { if(inserted_blocks.find(It->first) == inserted_blocks.end()) { CSketch* block = It->second; if(block->GetNumChildren() > 0) { CSketch* block_copy = new CSketch(*(It->second)); AddObject(block_copy); } } } if (m_make_as_sketch) { for (Sketches_t::const_iterator l_itSketch = m_sketches.begin(); l_itSketch != m_sketches.end(); l_itSketch++) { CSketch *pSketch = (CSketch *)(l_itSketch->second); if (pSketch->GetNumChildren() > 0) { ((CSketch *)l_itSketch->second)->OnEditString( l_itSketch->first.c_str() ); l_itSketch->second->ModifyByMatrix(m_ucs_matrix); if(m_undoable)wxGetApp().AddUndoably(l_itSketch->second, NULL, NULL ); else wxGetApp().Add( l_itSketch->second, NULL ); } // End if - then } } }
void CSketch::ExtractSeparateSketches(std::list<HeeksObj*> &new_separate_sketches, const bool allow_individual_objects /* = false */ ) { CSketch* re_ordered_sketch = NULL; CSketch* sketch = this; if(GetSketchOrder() == SketchOrderHasCircles) { std::list<HeeksObj*>::iterator It; for(It=m_objects.begin(); It!=m_objects.end() ;It++) { HeeksObj* object = *It; CSketch* new_object = new CSketch(); new_object->color = color; new_object->Add(object->MakeACopy(), NULL); new_separate_sketches.push_back(new_object); } } if(GetSketchOrder() == SketchOrderTypeBad) { // Duplicate and reorder the sketch to see if it's possible to make separate connected sketches. re_ordered_sketch = (CSketch*)(this->MakeACopy()); re_ordered_sketch->ReOrderSketch(SketchOrderTypeReOrder); sketch = re_ordered_sketch; } if(sketch->GetSketchOrder() == SketchOrderTypeMultipleCurves) { // Make separate connected sketches from the child elements. CSketchRelinker relinker(sketch->m_objects); relinker.Do(); for(std::list< std::list<HeeksObj*> >::iterator It = relinker.m_new_lists.begin(); It != relinker.m_new_lists.end(); It++) { std::list<HeeksObj*>& list = *It; CSketch* new_object = new CSketch(); new_object->color = color; for(std::list<HeeksObj*>::iterator It2 = list.begin(); It2 != list.end(); It2++) { HeeksObj* object = *It2; new_object->Add(object->MakeACopy(), NULL); } new_separate_sketches.push_back(new_object); } } else { // The sketch does not seem to relink into separate connected shapes. Just export // all the sketch's children as separate objects instead. if (allow_individual_objects) { for (HeeksObj *child = sketch->GetFirstChild(); child != NULL; child = sketch->GetNextChild()) { new_separate_sketches.push_back( child->MakeACopy() ); } } } if(re_ordered_sketch)delete re_ordered_sketch; }
void Run(){ CSketch* sketch = (CSketch*)(*wxGetApp().m_marked_list->list().begin()); CPart* part = new CPart(); wxGetApp().Add(part,NULL); sketch->HEEKSOBJ_OWNER->Remove(sketch); #ifdef MULTIPLE_OWNERS sketch->RemoveOwners(); #else sketch->m_owner = NULL; #endif part->Add(sketch,NULL); }
std::vector<TopoDS_Face> MultiPoly(std::list<CSketch*> sketches) { tol = wxGetApp().m_geom_tol; shapes.clear(); //first pass: build lists of closed shapes std::list<CSketch*>::iterator it; for(it = sketches.begin(); it!= sketches.end(); ++it) { CSketch* sketch = *it; //Copy this sketches objects into a new list std::list<EndedObject*> sketchobjs; HeeksObj* obj = sketch->GetFirstChild(); while(obj) { //TODO: for now we only handle EndedObject EndedObject* eobj = dynamic_cast<EndedObject*>(obj); if(eobj) { HArc* arc = dynamic_cast<HArc*>(obj); if(arc) { shapes.push_back(new FastArc(arc->A->m_p,arc->B->m_p,arc->C->m_p,arc->m_axis.Direction().Z() > 0, arc->GetCircle())); } else shapes.push_back(new FastLine(eobj->A->m_p,eobj->B->m_p)); } obj = sketch->GetNextChild(); } } //Get a list of all the intersection points Intersector *m_int = new SimpleIntersector(); std::map<FastCurve*, std::vector<Intersection> > intersections = m_int->Intersect(shapes); //Make our flashy double hashmap TwoDNearMap bcurves(tol); //Create a new list of bounded segment objects. Whose endpoints are locatable via hash //with the exception that the hash returns values within tolerance of the specified point std::map<FastCurve*, std::vector<Intersection> >::iterator it2; for(it2 = intersections.begin(); it2 != intersections.end(); ++it2) { FastCurve *tline = (*it2).first; std::vector<Intersection> inter = (*it2).second; for(unsigned i=0; i < inter.size()-1; i++) { double startu=tline->GetU(inter[i].X,inter[i].Y); double newu=tline->GetU(inter[i+1].X,inter[i+1].Y); CompoundSegment* segment; if(startu < newu) segment = new CompoundSegment(tline,tol,startu,newu); else segment = new CompoundSegment(tline,tol,newu,startu); bcurves.insert(inter[i].X,inter[i].Y,segment); bcurves.insert(inter[i+1].X,inter[i+1].Y,segment); startu = newu; } } //This gets the hashtable working bcurves.sort(); AnalyzeNearMap(bcurves); std::vector<CompoundSegment*> closed_shapes; //Create a new tree of boundedcurves, that is much smaller. follow all chains and attempt to remove //segments that are connected to only 2 other curves. This will yield a non-orientable graph //so our definition of polygons better be very graph theoretical std::vector<void*> returnvec; for(int i=0; i < bcurves.GetVecCount(); i++) { OneDNearMap* ptMap = bcurves.GetElement(i); double x_coord = bcurves.GetCoord(i); for(int j=0; j < ptMap->GetVecCount(); j++) { double y_coord = ptMap->GetCoord(j); if(!ptMap->IsValid(j)) continue; returnvec.clear(); bcurves.find(x_coord,y_coord,returnvec); if(returnvec.size() == 1) { //TODO: this means the current segment is part of an unclosed shape. However it is not clear that //this shape is fully concatenated or does not intersect a closed shape. these should probably be removed //prior to this loop continue; } if(returnvec.size() != 2) continue; //Concatenate the 2 groups and remove *it4 from the map CompoundSegment* seg1 = (CompoundSegment*)returnvec[0]; CompoundSegment* seg2 = (CompoundSegment*)returnvec[1]; if(seg1 == seg2) { //this means we have found a closed shape. Remove it from the bcurves and add it to a list of closed shapes //remove from the map bcurves.remove(x_coord,y_coord,seg1); bcurves.remove(x_coord,y_coord,seg2); closed_shapes.push_back(seg1); continue; } ConcatSegments(x_coord,y_coord,seg1,seg2,bcurves); } } //Now we have a graph of CompoundSegment*. These should be fast to traverse. //Non self intersecting shapes are already in closed_shapes //We could speed this up by regenerating near_map to get rid of removed references bool done=false; while(!done) { bool found=false; for(int i=0; i < bcurves.GetVecCount(); i++) { OneDNearMap* ptMap = bcurves.GetElement(i); double x_coord = bcurves.GetCoord(i); for(int j=0; j < ptMap->GetVecCount(); j++) { double y_coord = ptMap->GetCoord(j); if(!ptMap->IsValid(j)) continue; returnvec.clear(); bcurves.find(x_coord,y_coord,returnvec); //for most cases, returnvec should have 4 elements. more complicated cases have an even number > 4 //check for elements that are the same, which mean this polygon could terminate here, so terminate it //and merge the other CompoundSegments if there are only two remaining int nfound=0; for(size_t k=0; k < returnvec.size(); k++) { for(size_t l=k+1; l < returnvec.size(); l++) { if(returnvec[k] == returnvec[l]) { //this means we have found a closed shape. Remove it from the bcurves and add it to a list of closed shapes //remove from the map bcurves.remove(x_coord,y_coord,returnvec[k]); bcurves.remove(x_coord,y_coord,returnvec[l]); closed_shapes.push_back((CompoundSegment*)returnvec[k]); nfound+=2; found=true; } } } //now we know that no 2 elements in returnvec are equal. //make sure there are the right number of elements for our next op if(returnvec.size() - nfound != 2) continue; //Quick and dirty way to get the pointers returnvec.clear(); bcurves.find(x_coord,y_coord,returnvec); //Merge the segments and get them out of this coordinate ConcatSegments(x_coord,y_coord,(CompoundSegment*)returnvec[0],(CompoundSegment*)returnvec[1],bcurves); found=true; } } if(!found) done = true; } //Now that we have all closed shapes, we need to define the relationships. Since we know that they are not intersecting //3 kinds of things can happen. A shape is either inside, enclosing, adjacent, or unrelated to another. std::vector<std::vector<CompoundSegment*> > inside_of; inside_of.resize(closed_shapes.size()); for(unsigned i=0; i < closed_shapes.size(); i++) { for(unsigned j=0; j < closed_shapes.size(); j++) { //We can determine if a shape is inside or outside by finding the winding number of just 1 point with the //entire other polygon if(i==j) continue; int rays = closed_shapes[i]->GetRayIntersectionCount(closed_shapes[j]->Begin()); if(rays%2) { //Polygon J is inside of polygon I inside_of[j].push_back(closed_shapes[i]); int x=0; x++; } } } //This is used to reverse the ordering of a closed shape. Getting it to be CW or CCW //OCC is picky about the ordering when the polygon has holes for(unsigned i=0; i < closed_shapes.size(); i++) { closed_shapes[i]->Order(); #ifdef FORCEPOLYGONORDERING bool cw = closed_shapes[i]->GetCW(); if(!cw) { closed_shapes[i]->Reverse(); closed_shapes[i]->Order(); } #endif } //Sort these lists for easy comparison for(unsigned i=0; i < inside_of.size(); i++) { std::sort(inside_of[i].begin(),inside_of[i].end()); } //Now we want to descend into this thing. First find all shapes that are inside of nothing else std::vector<std::pair<CompoundSegment*,std::vector<CompoundSegment*> > > gold; find_level(true,gold,closed_shapes,inside_of,std::vector<CompoundSegment*>()); return TopoDSFaceAdaptor(gold); }