void OCCRegion::replaceFacesInternal(std::list<GFace*> &new_faces) { // we simply replace old faces by new faces in the structure TopExp_Explorer aExpS, aExpF; BRep_Builder aBB; TopoDS_Compound aCmp; aBB.MakeCompound(aCmp); TopoDS_Solid _s_replacement; aBB.MakeSolid(_s_replacement); _s_replacement.Orientation(s.Orientation()); aExpS.Init(s, TopAbs_SHELL); for (; aExpS.More(); aExpS.Next()) { const TopoDS_Shell& _shell=TopoDS::Shell(aExpS.Current()); TopoDS_Shell _shell_replacement; aBB.MakeShell(_shell_replacement); _shell_replacement.Orientation(_shell.Orientation()); aExpF.Init(_shell, TopAbs_FACE); for (; aExpF.More(); aExpF.Next()) { const TopoDS_Face& _face=TopoDS::Face(aExpF.Current()); TopoDS_Face _face_replacement; std::list<GFace*>::iterator it = l_faces.begin(); std::list<GFace*>::iterator it2 = new_faces.begin(); for ( ; it != l_faces.end() ; ++it,++it2){ OCCFace *occF = dynamic_cast<OCCFace*>(*it); if (occF){ TopoDS_Face oldf = occF->getTopoDS_Face(); if (oldf.IsSame(_face)){ _face_replacement = *((TopoDS_Face*)(*it2)->getNativePtr()); } else { oldf = occF->getTopoDS_FaceOld(); if (oldf.IsSame(_face)){ _face_replacement = *((TopoDS_Face*)(*it2)->getNativePtr()); } } } } if (_face_replacement.IsNull()){ Msg::Error("cannot find an face for gluing a region"); } if (_face_replacement.IsSame(_face)) { aBB.Add(_shell_replacement, _face); } else { if(FaceHaveDifferentOrientations(_face, _face_replacement)) _face_replacement.Reverse(); aBB.Add(_shell_replacement, _face_replacement); } } aBB.Add(_s_replacement, _shell_replacement); } s = _s_replacement; setup(); }
//======================================================================= // function: MakeContainer // purpose: //======================================================================= void GEOMAlgo_Tools3D::MakeContainer(const TopAbs_ShapeEnum theType, TopoDS_Shape& theC) { BRep_Builder aBB; // switch(theType) { case TopAbs_COMPOUND:{ TopoDS_Compound aC; aBB.MakeCompound(aC); theC=aC; } break; // case TopAbs_COMPSOLID:{ TopoDS_CompSolid aCS; aBB.MakeCompSolid(aCS); theC=aCS; } break; // case TopAbs_SOLID:{ TopoDS_Solid aSolid; aBB.MakeSolid(aSolid); theC=aSolid; } break; // // case TopAbs_SHELL:{ TopoDS_Shell aShell; aBB.MakeShell(aShell); theC=aShell; } break; // case TopAbs_WIRE: { TopoDS_Wire aWire; aBB.MakeWire(aWire); theC=aWire; } break; // default: break; } }
// constructor method int TopoShapeShellPy::PyInit(PyObject* args, PyObject* /*kwd*/) { PyObject *obj; if (!PyArg_ParseTuple(args, "O", &obj)) return -1; BRep_Builder builder; TopoDS_Shape shape; TopoDS_Shell shell; //BRepOffsetAPI_Sewing mkShell; builder.MakeShell(shell); try { Py::Sequence list(obj); for (Py::Sequence::iterator it = list.begin(); it != list.end(); ++it) { if (PyObject_TypeCheck((*it).ptr(), &(Part::TopoShapeFacePy::Type))) { const TopoDS_Shape& sh = static_cast<TopoShapeFacePy*>((*it).ptr())-> getTopoShapePtr()->_Shape; if (!sh.IsNull()) builder.Add(shell, sh); } } shape = shell; BRepCheck_Analyzer check(shell); if (!check.IsValid()) { ShapeUpgrade_ShellSewing sewShell; shape = sewShell.ApplySewing(shell); } if (shape.IsNull()) Standard_Failure::Raise("Shape is null"); if (shape.ShapeType() != TopAbs_SHELL) Standard_Failure::Raise("Shape is not a shell"); } catch (Standard_Failure) { Handle_Standard_Failure e = Standard_Failure::Caught(); PyErr_SetString(PartExceptionOCCError, e->GetMessageString()); return -1; } getTopoShapePtr()->_Shape = shape; return 0; }
Standard_Boolean ShHealOper_Sewing::getShells(const TopoDS_Shape& theSewShape) const { Standard_Boolean isDone = Standard_False; TopoDS_Shape aTmpShape = theSewShape; if(myNonManifoldMode) { TopoDS_Shell tempShell; BRep_Builder aB; aB.MakeShell(tempShell); for(TopExp_Explorer aExpf(theSewShape,TopAbs_FACE);aExpf.More(); aExpf.Next()) aB.Add(tempShell,aExpf.Current()); aTmpShape = tempShell; myContext->Replace(theSewShape,aTmpShape); } Handle(ShapeFix_Shell) asfs = new ShapeFix_Shell; asfs->SetContext(myContext); TopExp_Explorer aexpShell(aTmpShape,TopAbs_SHELL); for ( ; aexpShell.More(); aexpShell.Next()) isDone = (asfs->FixFaceOrientation(TopoDS::Shell(aexpShell.Current()), Standard_True,myNonManifoldMode) || isDone); return isDone; }
//////////////////////////////////////////////////////////////////////////////// // Construct TopoDS from BRL-CAD data //////////////////////////////////////////////////////////////////////////////// BRLTopo::BRLTopo(struct rt_arb_internal *arb) { TopoDS_Vertex v[8]; for(int i=0;i<8;i++) v[i]=BRepBuilderAPI_MakeVertex( gp_Pnt( scale*arb->pt[i][0], scale*arb->pt[i][1], scale*arb->pt[i][2] ) ); int arbn; if(!BRepTools::Compare(v[6],v[7])) arbn=8; else if(!BRepTools::Compare(v[4],v[5])) arbn=7; else if(!BRepTools::Compare(v[5],v[6])) arbn=6; else if(!BRepTools::Compare(v[0],v[3])) arbn=5; else arbn=4; switch(arbn) { case 8: { TopoDS_Edge e[12]; for(int i=0;i<4;i++) { e[i]=BRepBuilderAPI_MakeEdge(v[i],v[(i+1)%4]); e[i+4]=BRepBuilderAPI_MakeEdge(v[i+4],v[(i+1)%4+4]); e[i+8]=BRepBuilderAPI_MakeEdge(v[i],v[(i+4)%8]); } TopoDS_Wire w[6]; w[0]=BRepBuilderAPI_MakeWire(e[0],e[1],e[2],e[3]); w[1]=BRepBuilderAPI_MakeWire(e[4],e[5],e[6],e[7]); w[2]=BRepBuilderAPI_MakeWire(e[0],e[9],e[4],e[8]); w[3]=BRepBuilderAPI_MakeWire(e[1],e[10],e[5],e[9]); w[4]=BRepBuilderAPI_MakeWire(e[2],e[11],e[6],e[10]); w[5]=BRepBuilderAPI_MakeWire(e[3],e[8],e[7],e[11]); BRep_Builder BB; TopoDS_Shell shell; BB.MakeShell(shell); for(int i=0;i<6;i++) { TopoDS_Face f=BRepBuilderAPI_MakeFace(w[i]); BB.Add(shell,i? f.Reversed():f); } TopoDS_Solid solid; BB.MakeSolid(solid); BB.Add(solid,shell); ShapeFix_Solid sf(solid); sf.Perform(); shape=sf.Solid(); } break; case 6: { TopoDS_Edge e[9]; e[0]=BRepBuilderAPI_MakeEdge(v[0],v[1]); e[1]=BRepBuilderAPI_MakeEdge(v[1],v[2]); e[2]=BRepBuilderAPI_MakeEdge(v[2],v[3]); e[3]=BRepBuilderAPI_MakeEdge(v[3],v[0]); e[4]=BRepBuilderAPI_MakeEdge(v[0],v[4]); e[5]=BRepBuilderAPI_MakeEdge(v[1],v[4]); e[6]=BRepBuilderAPI_MakeEdge(v[2],v[6]); e[7]=BRepBuilderAPI_MakeEdge(v[3],v[6]); e[8]=BRepBuilderAPI_MakeEdge(v[4],v[6]); TopoDS_Wire w[5]; w[0]=BRepBuilderAPI_MakeWire(e[0],e[1],e[2],e[3]); w[1]=BRepBuilderAPI_MakeWire(e[0],e[4],e[5]); w[2]=BRepBuilderAPI_MakeWire(e[2],e[6],e[7]); w[3]=BRepBuilderAPI_MakeWire(e[3],e[4],e[8],e[7]); w[4]=BRepBuilderAPI_MakeWire(e[1],e[5],e[8],e[6]); BRep_Builder BB; #if 0 TopoDS_Compound result; BB.MakeCompound(result); for(int i=0;i<5;i++) { BB.Add(result,BRepBuilderAPI_MakeFace(w[i])); } shape=result; #else TopoDS_Shell shell; BB.MakeShell(shell); for(int i=0;i<5;i++) { TopoDS_Face f=BRepBuilderAPI_MakeFace(w[i]); BB.Add(shell,f); //i? f:f.Reversed()); } TopoDS_Solid solid; BB.MakeSolid(solid); BB.Add(solid,shell); ShapeFix_Solid sf(solid); sf.Perform(); shape=sf.Solid(); #endif } break; default: cerr << "Unhandled arb8 type n=" << arbn << '\n'; } }
BRLTopo::BRLTopo(struct rt_ell_internal *ell) { #if 0 gp_Pnt v(ell->v[0], ell->v[1], ell->v[2]); gp_Pnt a(v.Coord(1)+ell->a[0], v.Coord(2)+ell->a[1], v.Coord(3)+ell->a[2]); gp_Pnt b(v.Coord(1)+ell->b[0], v.Coord(2)+ell->b[1], v.Coord(3)+ell->b[2]); gp_Pnt c(v.Coord(1)+ell->c[0], v.Coord(2)+ell->c[1], v.Coord(3)+ell->c[2]); gp_Pnt aa(v.Coord(1)-ell->a[0], v.Coord(2)-ell->a[1], v.Coord(3)-ell->a[2]); gp_Pnt bb(v.Coord(1)-ell->b[0], v.Coord(2)-ell->b[1], v.Coord(3)-ell->b[2]); gp_Pnt cc(v.Coord(1)-ell->c[0], v.Coord(2)-ell->c[1], v.Coord(3)-ell->c[2]); Handle(Geom_Ellipse) sect1=GC_MakeEllipse(a, b, v); Handle(Geom_Ellipse) sect2=GC_MakeEllipse(a, c, v); Handle(Geom_Ellipse) sect3=GC_MakeEllipse(b, c, v); TopoDS_Edge e_ab[4]; e_ab[0]=BRepBuilderAPI_MakeEdge(sect1,a,b); e_ab[1]=BRepBuilderAPI_MakeEdge(sect1,b,aa); e_ab[2]=BRepBuilderAPI_MakeEdge(sect1,aa,bb); e_ab[3]=BRepBuilderAPI_MakeEdge(sect1,bb,a); TopoDS_Edge e_ac[4]; e_ac[0]=BRepBuilderAPI_MakeEdge(sect2,c,aa); e_ac[1]=BRepBuilderAPI_MakeEdge(sect2,a,c); e_ac[2]=BRepBuilderAPI_MakeEdge(sect2,aa,cc); e_ac[3]=BRepBuilderAPI_MakeEdge(sect2,cc,a); TopoDS_Edge e_bc[4]; e_bc[0]=BRepBuilderAPI_MakeEdge(sect3,b,c); e_bc[1]=BRepBuilderAPI_MakeEdge(sect3,c,bb); e_bc[2]=BRepBuilderAPI_MakeEdge(sect3,bb,cc); e_bc[3]=BRepBuilderAPI_MakeEdge(sect3,cc,b); // FIXME, BRepFill_Filling? TopoDS_Solid sph=BRepPrimAPI_MakeSphere(v,ell->a[0]); TopoDS_Face init; for(TopExp_Explorer p(sph,TopAbs_FACE); p.More(); p.Next()) init=TopoDS::Face(p.Current()); BRepFill_Filling face1; //face1.LoadInitSurface(init); face1.Add(e_ab[0],GeomAbs_C0); face1.Add(e_ab[1],GeomAbs_C0); face1.Add(e_ac[0],GeomAbs_C0); face1.Add(e_ac[1],GeomAbs_C0); face1.Add(e_bc[0],GeomAbs_C0,false); face1.Build(); BRepFill_Filling face2; //face2.LoadInitSurface(init); face2.Add(e_ab[2],GeomAbs_C0); face2.Add(e_ab[3],GeomAbs_C0); face2.Add(e_ac[2],GeomAbs_C0); face2.Add(e_ac[3],GeomAbs_C0); face2.Add(e_bc[2],GeomAbs_C0,false); face2.Build(); BRepFill_Filling face3; //face3.LoadInitSurface(init); face3.Add(e_ab[2],GeomAbs_C0); face3.Add(e_ab[3],GeomAbs_C0); face3.Add(e_ac[0],GeomAbs_C0); face3.Add(e_ac[1],GeomAbs_C0); face3.Add(e_bc[1],GeomAbs_C0,false); face3.Build(); BRepFill_Filling face4; //face4.LoadInitSurface(init); face4.Add(e_ab[0],GeomAbs_C0); face4.Add(e_ab[1],GeomAbs_C0); face4.Add(e_ac[2],GeomAbs_C0); face4.Add(e_ac[3],GeomAbs_C0); face4.Add(e_bc[3],GeomAbs_C0,false); face4.Build(); BRep_Builder BB; TopoDS_Shell result; BB.MakeShell(result); BB.Add(result,face1.Face()); BB.Add(result,face2.Face().Reversed()); BB.Add(result,face3.Face()); BB.Add(result,face4.Face().Reversed()); shape=BRepBuilderAPI_MakeSolid(result); #else /* FIXME, we only support spheres at the moment. */ gp_Pnt v(scale*ell->v[0], scale*ell->v[1], scale*ell->v[2]); TopoDS_Solid sph=BRepPrimAPI_MakeSphere(v,scale*ell->a[0]); shape=sph; #endif }
//======================================================================= //function : MakeScaledPrism //purpose : //======================================================================= TopoDS_Shape GEOMImpl_PrismDriver::MakeScaledPrism (const TopoDS_Shape& theShapeBase, const gp_Vec& theVector, const Standard_Real theScaleFactor, const gp_Pnt& theCDG, bool isCDG) { TopoDS_Shape aShape; BRep_Builder B; // 1. aCDG = geompy.MakeCDG(theBase) gp_Pnt aCDG = theCDG; if (!isCDG) { gp_Ax3 aPos = GEOMImpl_IMeasureOperations::GetPosition(theShapeBase); aCDG = aPos.Location(); } TopoDS_Shape aShapeCDG_1 = BRepBuilderAPI_MakeVertex(aCDG).Shape(); // Process case of several given shapes if (theShapeBase.ShapeType() == TopAbs_COMPOUND || theShapeBase.ShapeType() == TopAbs_SHELL) { int nbSub = 0; TopoDS_Shape aShapeI; TopoDS_Compound aCompound; B.MakeCompound(aCompound); TopoDS_Iterator It (theShapeBase, Standard_True, Standard_True); for (; It.More(); It.Next()) { nbSub++; aShapeI = MakeScaledPrism(It.Value(), theVector, theScaleFactor, aCDG, true); B.Add(aCompound, aShapeI); } if (nbSub == 1) aShape = aShapeI; else if (nbSub > 1) aShape = GEOMImpl_GlueDriver::GlueFaces(aCompound, Precision::Confusion(), Standard_True); return aShape; } // 2. Scale = geompy.MakeScaleTransform(theBase, aCDG, theScaleFactor) // Bug 6839: Check for standalone (not included in faces) degenerated edges TopTools_IndexedDataMapOfShapeListOfShape aEFMap; TopExp::MapShapesAndAncestors(theShapeBase, TopAbs_EDGE, TopAbs_FACE, aEFMap); Standard_Integer i, nbE = aEFMap.Extent(); for (i = 1; i <= nbE; i++) { TopoDS_Shape anEdgeSh = aEFMap.FindKey(i); if (BRep_Tool::Degenerated(TopoDS::Edge(anEdgeSh))) { const TopTools_ListOfShape& aFaces = aEFMap.FindFromIndex(i); if (aFaces.IsEmpty()) Standard_ConstructionError::Raise ("Scaling aborted : cannot scale standalone degenerated edge"); } } // Perform Scaling gp_Trsf aTrsf; aTrsf.SetScale(aCDG, theScaleFactor); BRepBuilderAPI_Transform aBRepTrsf (theShapeBase, aTrsf, Standard_False); TopoDS_Shape aScale = aBRepTrsf.Shape(); // 3. aBase2 = geompy.MakeTranslationVectorDistance(Scale, theVec, theH) gp_Trsf aTrsf3; aTrsf3.SetTranslation(theVector); TopLoc_Location aLocOrig = aScale.Location(); gp_Trsf aTrsfOrig = aLocOrig.Transformation(); TopLoc_Location aLocRes (aTrsf3 * aTrsfOrig); TopoDS_Shape aBase2 = aScale.Located(aLocRes); // 4. aCDG_2 = geompy.MakeTranslationVectorDistance(aCDG, theVec, theH) gp_Pnt aCDG_2 = aCDG.Translated(theVector); TopoDS_Shape aShapeCDG_2 = BRepBuilderAPI_MakeVertex(aCDG_2).Shape(); // 5. Vector = geompy.MakeVector(aCDG, aCDG_2) TopoDS_Shape aShapeVec = BRepBuilderAPI_MakeEdge(aCDG, aCDG_2).Shape(); TopoDS_Edge anEdge = TopoDS::Edge(aShapeVec); TopoDS_Wire aWirePath = BRepBuilderAPI_MakeWire(anEdge); // 6. aPrism = geompy.MakePipeWithDifferentSections([theBase, aBase2], [aCDG, aCDG_2], Vector, False, False) Handle(TopTools_HSequenceOfShape) aBases = new TopTools_HSequenceOfShape; aBases->Append(theShapeBase); aBases->Append(aBase2); Handle(TopTools_HSequenceOfShape) aLocs = new TopTools_HSequenceOfShape; aLocs->Append(aShapeCDG_1); aLocs->Append(aShapeCDG_2); aShape = GEOMImpl_PipeDriver::CreatePipeWithDifferentSections(aWirePath, aBases, aLocs, false, false); // 7. Make a solid, if possible if (theShapeBase.ShapeType() == TopAbs_FACE) { BRepBuilderAPI_Sewing aSewing (Precision::Confusion()*10.0); TopExp_Explorer expF (aShape, TopAbs_FACE); Standard_Integer ifa = 0; for (; expF.More(); expF.Next()) { aSewing.Add(expF.Current()); ifa++; } if (ifa > 0) { aSewing.Perform(); TopoDS_Shape aShell; TopoDS_Shape sh = aSewing.SewedShape(); if (sh.ShapeType() == TopAbs_FACE && ifa == 1) { // case for creation of shell from one face TopoDS_Shell ss; B.MakeShell(ss); B.Add(ss,sh); aShell = ss; } else { TopExp_Explorer exp (sh, TopAbs_SHELL); Standard_Integer ish = 0; for (; exp.More(); exp.Next()) { aShell = exp.Current(); ish++; } if (ish != 1) aShell = sh; } BRepCheck_Shell chkShell (TopoDS::Shell(aShell)); if (chkShell.Closed() == BRepCheck_NoError) { TopoDS_Solid Sol; B.MakeSolid(Sol); B.Add(Sol, aShell); BRepClass3d_SolidClassifier SC (Sol); SC.PerformInfinitePoint(Precision::Confusion()); if (SC.State() == TopAbs_IN) { B.MakeSolid(Sol); B.Add(Sol, aShell.Reversed()); } aShape = Sol; } } } return aShape; }
bool FaceUniter::process() { if (workShell.IsNull()) return false; modifiedShapes.clear(); deletedShapes.clear(); typeObjects.push_back(&getPlaneObject()); typeObjects.push_back(&getCylinderObject()); //add more face types. ModelRefine::FaceTypeSplitter splitter; splitter.addShell(workShell); std::vector<FaceTypedBase *>::iterator typeIt; for(typeIt = typeObjects.begin(); typeIt != typeObjects.end(); ++typeIt) splitter.registerType((*typeIt)->getType()); splitter.split(); ModelRefine::FaceVectorType facesToRemove; ModelRefine::FaceVectorType facesToSew; ModelRefine::FaceAdjacencySplitter adjacencySplitter(workShell); for(typeIt = typeObjects.begin(); typeIt != typeObjects.end(); ++typeIt) { ModelRefine::FaceVectorType typedFaces = splitter.getTypedFaceVector((*typeIt)->getType()); ModelRefine::FaceEqualitySplitter equalitySplitter; equalitySplitter.split(typedFaces, *typeIt); for (std::size_t indexEquality(0); indexEquality < equalitySplitter.getGroupCount(); ++indexEquality) { adjacencySplitter.split(equalitySplitter.getGroup(indexEquality)); // std::cout << " adjacency group count: " << adjacencySplitter.getGroupCount() << std::endl; for (std::size_t adjacentIndex(0); adjacentIndex < adjacencySplitter.getGroupCount(); ++adjacentIndex) { // std::cout << " face count is: " << adjacencySplitter.getGroup(adjacentIndex).size() << std::endl; TopoDS_Face newFace = (*typeIt)->buildFace(adjacencySplitter.getGroup(adjacentIndex)); if (!newFace.IsNull()) { facesToSew.push_back(newFace); if (facesToRemove.capacity() <= facesToRemove.size() + adjacencySplitter.getGroup(adjacentIndex).size()) facesToRemove.reserve(facesToRemove.size() + adjacencySplitter.getGroup(adjacentIndex).size()); FaceVectorType temp = adjacencySplitter.getGroup(adjacentIndex); facesToRemove.insert(facesToRemove.end(), temp.begin(), temp.end()); // the first shape will be marked as modified, i.e. replaced by newFace, all others are marked as deleted if (!temp.empty()) { modifiedShapes.push_back(std::make_pair(temp.front(), newFace)); deletedShapes.insert(deletedShapes.end(), temp.begin()+1, temp.end()); } } } } } if (facesToSew.size() > 0) { modifiedSignal = true; workShell = ModelRefine::removeFaces(workShell, facesToRemove); TopExp_Explorer xp; bool emptyShell = true; for (xp.Init(workShell, TopAbs_FACE); xp.More(); xp.Next()) { emptyShell = false; break; } if (!emptyShell || facesToSew.size() > 1) { BRepBuilderAPI_Sewing sew; sew.Add(workShell); FaceVectorType::iterator sewIt; for(sewIt = facesToSew.begin(); sewIt != facesToSew.end(); ++sewIt) sew.Add(*sewIt); sew.Perform(); workShell = TopoDS::Shell(sew.SewedShape()); // update the list of modifications for (std::vector<ShapePairType>::iterator it = modifiedShapes.begin(); it != modifiedShapes.end(); ++it) { if (sew.IsModified(it->second)) { it->second = sew.Modified(it->second); break; } } } else { // workShell has no more faces and we add exactly one face BRep_Builder builder; builder.MakeShell(workShell); FaceVectorType::iterator sewIt; for(sewIt = facesToSew.begin(); sewIt != facesToSew.end(); ++sewIt) builder.Add(workShell, *sewIt); } BRepLib_FuseEdges edgeFuse(workShell, Standard_True); TopTools_DataMapOfShapeShape affectedFaces; edgeFuse.Faces(affectedFaces); TopTools_DataMapIteratorOfDataMapOfShapeShape mapIt; for (mapIt.Initialize(affectedFaces); mapIt.More(); mapIt.Next()) { ShapeFix_Face faceFixer(TopoDS::Face(mapIt.Value())); faceFixer.Perform(); } workShell = TopoDS::Shell(edgeFuse.Shape()); // update the list of modifications TopTools_DataMapOfShapeShape faceMap; edgeFuse.Faces(faceMap); for (std::vector<ShapePairType>::iterator it = modifiedShapes.begin(); it != modifiedShapes.end(); ++it) { if (faceMap.IsBound(it->second)) { const TopoDS_Shape& value = faceMap.Find(it->second); if (!value.IsSame(it->second)) it->second = value; } } } return true; }
bool FaceUniter::process() { if (workShell.IsNull()) return false; modifiedShapes.clear(); deletedShapes.clear(); typeObjects.push_back(&getPlaneObject()); typeObjects.push_back(&getCylinderObject()); //add more face types. ModelRefine::FaceTypeSplitter splitter; splitter.addShell(workShell); std::vector<FaceTypedBase *>::iterator typeIt; for(typeIt = typeObjects.begin(); typeIt != typeObjects.end(); ++typeIt) splitter.registerType((*typeIt)->getType()); splitter.split(); ModelRefine::FaceVectorType facesToRemove; ModelRefine::FaceVectorType facesToSew; ModelRefine::FaceAdjacencySplitter adjacencySplitter(workShell); for(typeIt = typeObjects.begin(); typeIt != typeObjects.end(); ++typeIt) { ModelRefine::FaceVectorType typedFaces = splitter.getTypedFaceVector((*typeIt)->getType()); ModelRefine::FaceEqualitySplitter equalitySplitter; equalitySplitter.split(typedFaces, *typeIt); for (std::size_t indexEquality(0); indexEquality < equalitySplitter.getGroupCount(); ++indexEquality) { adjacencySplitter.split(equalitySplitter.getGroup(indexEquality)); // std::cout << " adjacency group count: " << adjacencySplitter.getGroupCount() << std::endl; for (std::size_t adjacentIndex(0); adjacentIndex < adjacencySplitter.getGroupCount(); ++adjacentIndex) { // std::cout << " face count is: " << adjacencySplitter.getGroup(adjacentIndex).size() << std::endl; TopoDS_Face newFace = (*typeIt)->buildFace(adjacencySplitter.getGroup(adjacentIndex)); if (!newFace.IsNull()) { facesToSew.push_back(newFace); if (facesToRemove.capacity() <= facesToRemove.size() + adjacencySplitter.getGroup(adjacentIndex).size()) facesToRemove.reserve(facesToRemove.size() + adjacencySplitter.getGroup(adjacentIndex).size()); FaceVectorType temp = adjacencySplitter.getGroup(adjacentIndex); facesToRemove.insert(facesToRemove.end(), temp.begin(), temp.end()); // the first shape will be marked as modified, i.e. replaced by newFace, all others are marked as deleted // jrheinlaender: IMHO this is not correct because references to the deleted faces will be broken, whereas they should // be replaced by references to the new face. To achieve this all shapes should be marked as // modified, producing one single new face. This is the inverse behaviour to faces that are split e.g. // by a boolean cut, where one old shape is marked as modified, producing multiple new shapes if (!temp.empty()) { for (FaceVectorType::iterator f = temp.begin(); f != temp.end(); ++f) modifiedShapes.push_back(std::make_pair(*f, newFace)); } } } } } if (facesToSew.size() > 0) { modifiedSignal = true; workShell = ModelRefine::removeFaces(workShell, facesToRemove); TopExp_Explorer xp; bool emptyShell = true; for (xp.Init(workShell, TopAbs_FACE); xp.More(); xp.Next()) { emptyShell = false; break; } if (!emptyShell || facesToSew.size() > 1) { BRepBuilderAPI_Sewing sew; sew.Add(workShell); FaceVectorType::iterator sewIt; for(sewIt = facesToSew.begin(); sewIt != facesToSew.end(); ++sewIt) sew.Add(*sewIt); sew.Perform(); try { workShell = TopoDS::Shell(sew.SewedShape()); } catch (Standard_Failure) { return false; } // update the list of modifications for (std::vector<ShapePairType>::iterator it = modifiedShapes.begin(); it != modifiedShapes.end(); ++it) { if (sew.IsModified(it->second)) { it->second = sew.Modified(it->second); break; } } } else { // workShell has no more faces and we add exactly one face BRep_Builder builder; builder.MakeShell(workShell); FaceVectorType::iterator sewIt; for(sewIt = facesToSew.begin(); sewIt != facesToSew.end(); ++sewIt) builder.Add(workShell, *sewIt); } BRepLib_FuseEdges edgeFuse(workShell); // TODO: change this version after occ fix. Freecad Mantis 1450 #if OCC_VERSION_HEX <= 0x070000 TopTools_IndexedMapOfShape map; collectConicEdges(workShell, map); edgeFuse.AvoidEdges(map); #endif TopTools_DataMapOfShapeShape affectedFaces; edgeFuse.Faces(affectedFaces); TopTools_DataMapIteratorOfDataMapOfShapeShape mapIt; for (mapIt.Initialize(affectedFaces); mapIt.More(); mapIt.Next()) { ShapeFix_Face faceFixer(TopoDS::Face(mapIt.Value())); faceFixer.Perform(); } workShell = TopoDS::Shell(edgeFuse.Shape()); // update the list of modifications TopTools_DataMapOfShapeShape faceMap; edgeFuse.Faces(faceMap); for (mapIt.Initialize(faceMap); mapIt.More(); mapIt.Next()) { bool isModifiedFace = false; for (std::vector<ShapePairType>::iterator it = modifiedShapes.begin(); it != modifiedShapes.end(); ++it) { if (mapIt.Key().IsSame(it->second)) { // Note: IsEqual() for some reason does not work it->second = mapIt.Value(); isModifiedFace = true; } } if (!isModifiedFace) { // Catch faces that were not united but whose boundary was changed (probably because // several adjacent faces were united) // See https://sourceforge.net/apps/mantisbt/free-cad/view.php?id=873 modifiedShapes.push_back(std::make_pair(mapIt.Key(), mapIt.Value())); } } // Handle edges that were fused. See https://sourceforge.net/apps/mantisbt/free-cad/view.php?id=873 TopTools_DataMapOfIntegerListOfShape oldEdges; TopTools_DataMapOfIntegerShape newEdges; edgeFuse.Edges(oldEdges); edgeFuse.ResultEdges(newEdges); TopTools_DataMapIteratorOfDataMapOfIntegerListOfShape edgeMapIt; for (edgeMapIt.Initialize(oldEdges); edgeMapIt.More(); edgeMapIt.Next()) { const TopTools_ListOfShape& edges = edgeMapIt.Value(); int idx = edgeMapIt.Key(); TopTools_ListIteratorOfListOfShape edgeIt; for (edgeIt.Initialize(edges); edgeIt.More(); edgeIt.Next()) { modifiedShapes.push_back(std::make_pair(edgeIt.Value(), newEdges(idx))); } // TODO: Handle vertices that have disappeared in the fusion of the edges } } return true; }
//======================================================================= //function : BuildDraftSolid //purpose : //======================================================================= void GEOMAlgo_Builder::BuildDraftSolid (const TopoDS_Shape& theSolid, TopoDS_Shape& theDraftSolid, TopTools_ListOfShape& theLIF) { myErrorStatus=0; // NMTTools_PaveFiller* pPF=myPaveFiller; const Handle(IntTools_Context)& aCtx= pPF->Context(); // Standard_Boolean bToReverse; Standard_Integer iFlag; TopAbs_Orientation aOrF, aOrSh, aOrSd; TopoDS_Iterator aIt1, aIt2; TopTools_ListIteratorOfListOfShape aItS; BRep_Builder aBB; TopoDS_Shell aShD; TopoDS_Shape aFSDx, aFx; // aOrSd=theSolid.Orientation(); theDraftSolid.Orientation(aOrSd); // aIt1.Initialize(theSolid); for (; aIt1.More(); aIt1.Next()) { const TopoDS_Shape& aSh=aIt1.Value(); if(aSh.ShapeType()!=TopAbs_SHELL) { continue; // mb internal edges,vertices } // aOrSh=aSh.Orientation(); aBB.MakeShell(aShD); aShD.Orientation(aOrSh); iFlag=0; // aIt2.Initialize(aSh); for (; aIt2.More(); aIt2.Next()) { const TopoDS_Shape& aF=aIt2.Value(); aOrF=aF.Orientation(); // if (myImages.HasImage(aF)) { const TopTools_ListOfShape& aLSp=myImages.Image(aF); aItS.Initialize(aLSp); for (; aItS.More(); aItS.Next()) { aFx=aItS.Value(); // if (mySameDomainShapes.Contains(aFx)) { aFSDx=mySameDomainShapes.FindFromKey(aFx); // if (aOrF==TopAbs_INTERNAL) { aFSDx.Orientation(aOrF); theLIF.Append(aFSDx); } else { bToReverse=GEOMAlgo_Tools3D::IsSplitToReverse(aFSDx, aF, aCtx); if (bToReverse) { aFSDx.Reverse(); } // iFlag=1; aBB.Add(aShD, aFSDx); } }// if (mySameDomainShapes.Contains(aFx)) { else { aFx.Orientation(aOrF); if (aOrF==TopAbs_INTERNAL) { theLIF.Append(aFx); } else{ iFlag=1; aBB.Add(aShD, aFx); } } } } //if (myImages.HasImage(aF)) { // else { if (aOrF==TopAbs_INTERNAL) { theLIF.Append(aF); } else{ iFlag=1; aBB.Add(aShD, aF); } } } //for (; aIt2.More(); aIt2.Next()) { // if (iFlag) { aBB.Add(theDraftSolid, aShD); } } //for (; aIt1.More(); aIt1.Next()) { }
App::DocumentObjectExecReturn *Fractal::execute(void) { faces.clear(); //Appel de la fonction de generation avec des valeurs prereglees(taille) et la valeur de l'utilisateur //sierpin([-7, -4, 0], [0, 8, 0], [7, -4, 0], [0, 0, 11], 6) //sierpin(Base::Vector3d(-5, -5, -5), Base::Vector3d(5, 5, -5), Base::Vector3d(-5, 5, 5), Base::Vector3d(5, -5, 5), 1, Nodes.getValues()); sierpin(Base::Vector3d(-Length.getValue(), -Width.getValue(), -Height.getValue()), Base::Vector3d(Length.getValue(), Width.getValue(), -Height.getValue()), Base::Vector3d(-Length.getValue(), Width.getValue(), Height.getValue()), Base::Vector3d(Length.getValue(), -Width.getValue(), Height.getValue()), Depth.getValue(), Nodes.getValues()); //Sponge(); /*//Creation du shell avec la liste des faces myShell = Part.makeShell(partFaces); // Creation du polygon avec le shell mySolid = Part.makeSolid(myShell); // Mise a jour de l'orientation des faces mySolidRev = mySolid.copy(); mySolidRev.reverse(); //Affichage du solide Part.show(mySolidRev);*/ BRepBuilderAPI_MakePolygon poly; //const std::vector<Base::Vector3d> nodes = Nodes; /*_nodes.push_back(Base::Vector3d(0, 0, 0)); _nodes.push_back(Base::Vector3d(0, 0, 1)); _nodes.push_back(Base::Vector3d(0, 0, 3)); _nodes.push_back(Base::Vector3d(0, 0, 5)); _nodes.push_back(Base::Vector3d(0, 5, 0)); _nodes.push_back(Base::Vector3d(0, 0, 8));*/ /*std::string s = std::to_string(_nodes.size()); char const *pchar = s.c_str(); Base::Console().Message(pchar); Base::Console().Log(pchar);*/ for (std::vector<Base::Vector3d>::const_iterator it = _nodes.begin(); it != _nodes.end(); ++it) { gp_Pnt pnt(it->x, it->y, it->z); poly.Add(pnt); } if (!poly.IsDone()) throw Base::Exception("Cannot create polygon because less than two vetices are given"); //TopoDS_Wire wire = poly.Wire(); //BRepBuilderAPI_MakeFace makeFace(poly.Wire()); /*gp_Pnt point1 = gp_Pnt(1,0,0); gp_Pnt point2 = gp_Pnt(1,1,0); gp_Pnt point3 = gp_Pnt(1,0,1);*/ //TopoDS_Wire wire = BRepBuilderAPI_MakePolygon(, Standard_True); //TopoDS_Face face = BRepBuilderAPI_MakeFace(wire, Standard_True); //TopoDS_Shape s; /*if (makeFace.Error() == BRepBuilderAPI_FaceDone) { TopoDS_Face faceCurrent = makeFace.Face(); } BRepBuilderAPI_MakeFace makeFace(faceCurrent); makeFace.Add(MP.Wire()); if (makeFace.Error() == BRepBuilderAPI_FaceDone) { faceCurrent = makeFace.Face(); }*/ //this->Shape.setValue(); //TopoDS_Face tf; //BRepBuilderAPI_MakeFace mkFace(TopoDS::Wire(sh)); //Handle_Geom_Surface gs; //Handle<Geom_Surface> dd; //gs.Access = 0; /*RepOffsetAPI_MakeOffsetShape mkOffset(this->_Shape, offset, tol, BRepOffset_Mode(offsetMode), intersection ? Standard_True : Standard_False, selfInter ? Standard_True : Standard_False, GeomAbs_JoinType(join)); if (!fill) return res; #if 1 //s=Part.makePlane(10,10) //s.makeOffsetShape(1.0,0.01,False,False,0,0,True)*/ //BRepOffsetAPI_MakeOffsetShape myOffsetShape; //TopoShape ts; //myOffsetShape = ts.makeOffsetShape(1.0, 0.01, False, False, 0, 0, True); //const TopoDS_Shape& res = myOffsetShape.Shape(); BRep_Builder builder; TopoDS_Shell shell; builder.MakeShell(shell); /*s = std::to_string(faces.size()); pchar = s.c_str(); Base::Console().Message(pchar); Base::Console().Log(pchar);*/ for (int i = 0; i < faces.size(); i++) { builder.Add(shell, faces[i]); //this->Shape.setValue(shell); } //this->Shape.setValue(builder.sh); //BRepBuilderAPI_MakeShell myShell(gs); //const TopoDS_Shell& td = gs.sh; /*TopoDS_Solid mysolid; builder.MakeSolid(mysolid); builder.Add(mysolid, shell);*/ BRepBuilderAPI_MakeSolid mySolid(shell); this->Shape.setValue(mySolid.Shape()); return App::DocumentObject::StdReturn; }