void OCCSurface::get_parents_virt( DLIList<TopologyBridge*>& parents ) { if(myShell) //shell or sheet body { parents.append(myShell); return; } OCCQueryEngine* oqe = (OCCQueryEngine*) get_geometry_query_engine(); OCCBody * body = NULL; DLIList <OCCBody* > *bodies = oqe->BodyList; TopTools_IndexedDataMapOfShapeListOfShape M; for(int i = 0; i < bodies->size(); i++) { body = bodies->get_and_step(); TopExp::MapShapesAndAncestors(*(body->get_TopoDS_Shape()), TopAbs_FACE, TopAbs_SHELL, M); if(!M.Contains(*(get_TopoDS_Face()))) continue; const TopTools_ListOfShape& ListOfShapes = M.FindFromKey(*(get_TopoDS_Face())); if (!ListOfShapes.IsEmpty()) { TopTools_ListIteratorOfListOfShape it(ListOfShapes) ; for (;it.More(); it.Next()) { TopoDS_Shell Shell = TopoDS::Shell(it.Value()); int k = oqe->OCCMap->Find(Shell); parents.append((OCCShell*)(oqe->OccToCGM->find(k))->second); } } } }
App::DocumentObjectExecReturn *Chamfer::execute(void) { App::DocumentObject* link = Base.getValue(); if (!link) return new App::DocumentObjectExecReturn("No object linked"); if (!link->getTypeId().isDerivedFrom(Part::Feature::getClassTypeId())) return new App::DocumentObjectExecReturn("Linked object is not a Part object"); Part::Feature *base = static_cast<Part::Feature*>(Base.getValue()); const Part::TopoShape& TopShape = base->Shape.getShape(); if (TopShape._Shape.IsNull()) return new App::DocumentObjectExecReturn("Cannot chamfer invalid shape"); const std::vector<std::string>& SubVals = Base.getSubValuesStartsWith("Edge"); if (SubVals.size() == 0) return new App::DocumentObjectExecReturn("No edges specified"); double size = Size.getValue(); this->positionByBase(); // create an untransformed copy of the base shape Part::TopoShape baseShape(TopShape); baseShape.setTransform(Base::Matrix4D()); try { BRepFilletAPI_MakeChamfer mkChamfer(baseShape._Shape); TopTools_IndexedMapOfShape mapOfEdges; TopTools_IndexedDataMapOfShapeListOfShape mapEdgeFace; TopExp::MapShapesAndAncestors(baseShape._Shape, TopAbs_EDGE, TopAbs_FACE, mapEdgeFace); TopExp::MapShapes(baseShape._Shape, TopAbs_EDGE, mapOfEdges); for (std::vector<std::string>::const_iterator it=SubVals.begin(); it != SubVals.end(); ++it) { TopoDS_Edge edge = TopoDS::Edge(baseShape.getSubShape(it->c_str())); const TopoDS_Face& face = TopoDS::Face(mapEdgeFace.FindFromKey(edge).First()); mkChamfer.Add(size, edge, face); } mkChamfer.Build(); if (!mkChamfer.IsDone()) return new App::DocumentObjectExecReturn("Failed to create chamfer"); TopoDS_Shape shape = mkChamfer.Shape(); if (shape.IsNull()) return new App::DocumentObjectExecReturn("Resulting shape is null"); TopTools_ListOfShape aLarg; aLarg.Append(baseShape._Shape); if (!BRepAlgo::IsValid(aLarg, shape, Standard_False, Standard_False)) { return new App::DocumentObjectExecReturn("Resulting shape is invalid"); } this->Shape.setValue(shape); return App::DocumentObject::StdReturn; } catch (Standard_Failure) { Handle_Standard_Failure e = Standard_Failure::Caught(); return new App::DocumentObjectExecReturn(e->GetMessageString()); } }
//======================================================================= //function : MakeInternalWires //purpose : //======================================================================= void MakeInternalWires(const TopTools_MapOfShape& theME, TopTools_ListOfShape& theWires) { TopTools_MapIteratorOfMapOfShape aItM; TopTools_MapOfShape aAddedMap; TopTools_ListIteratorOfListOfShape aItE; TopTools_IndexedDataMapOfShapeListOfShape aMVE; BRep_Builder aBB; // aItM.Initialize(theME); for (; aItM.More(); aItM.Next()) { const TopoDS_Shape& aE=aItM.Key(); TopExp::MapShapesAndAncestors(aE, TopAbs_VERTEX, TopAbs_EDGE, aMVE); } // aItM.Initialize(theME); for (; aItM.More(); aItM.Next()) { TopoDS_Shape aEE=aItM.Key(); if (!aAddedMap.Add(aEE)) { continue; } // // make a new shell TopoDS_Wire aW; aBB.MakeWire(aW); aEE.Orientation(TopAbs_INTERNAL); aBB.Add(aW, aEE); // TopoDS_Iterator aItAdded (aW); for (; aItAdded.More(); aItAdded.Next()) { const TopoDS_Shape& aE =aItAdded.Value(); // TopExp_Explorer aExp(aE, TopAbs_VERTEX); for (; aExp.More(); aExp.Next()) { const TopoDS_Shape& aV =aExp.Current(); const TopTools_ListOfShape& aLE=aMVE.FindFromKey(aV); aItE.Initialize(aLE); for (; aItE.More(); aItE.Next()) { TopoDS_Shape aEL=aItE.Value(); if (aAddedMap.Add(aEL)){ aEL.Orientation(TopAbs_INTERNAL); aBB.Add(aW, aEL); } } } } theWires.Append(aW); } }
TopoDS_Edge StdMeshers_Hexa_3D::EdgeNotInFace(SMESH_Mesh & aMesh, const TopoDS_Shape & aShape, const TopoDS_Face & aFace, const TopoDS_Vertex & aVertex, const TopTools_IndexedDataMapOfShapeListOfShape & MS) { //MESSAGE("StdMeshers_Hexa_3D::EdgeNotInFace"); TopTools_IndexedDataMapOfShapeListOfShape MF; TopExp::MapShapesAndAncestors(aFace, TopAbs_VERTEX, TopAbs_EDGE, MF); const TopTools_ListOfShape & ancestorsInSolid = MS.FindFromKey(aVertex); const TopTools_ListOfShape & ancestorsInFace = MF.FindFromKey(aVertex); // SCRUTE(ancestorsInSolid.Extent()); // SCRUTE(ancestorsInFace.Extent()); ASSERT(ancestorsInSolid.Extent() == 6); // 6 (edges doublees) ASSERT(ancestorsInFace.Extent() == 2); TopoDS_Edge E; E.Nullify(); TopTools_ListIteratorOfListOfShape its(ancestorsInSolid); for (; its.More(); its.Next()) { TopoDS_Shape ancestor = its.Value(); TopTools_ListIteratorOfListOfShape itf(ancestorsInFace); bool isInFace = false; for (; itf.More(); itf.Next()) { TopoDS_Shape ancestorInFace = itf.Value(); if (ancestorInFace.IsSame(ancestor)) { isInFace = true; break; } } if (!isInFace) { E = TopoDS::Edge(ancestor); break; } } return E; }
CubitStatus OCCSurface::get_bodies(DLIList<OCCBody*>& bodies) { TopoDS_Face* topo_face = this->get_TopoDS_Face(); OCCQueryEngine* oqe = OCCQueryEngine::instance(); DLIList <OCCBody* > *all_bodies = oqe->BodyList; TopTools_IndexedDataMapOfShapeListOfShape M; OCCBody * body = NULL; for(int j = 0; j < all_bodies->size(); j++) { body = all_bodies->get_and_step(); TopExp_Explorer Ex; TopoDS_Face the_face; TopoDS_Shape ashape = *(body->get_TopoDS_Shape()); M.Clear(); TopExp::MapShapesAndAncestors(ashape, TopAbs_FACE, TopAbs_COMPSOLID, M); if(!M.Contains(*topo_face)) continue; bodies.append_unique(body); } return CUBIT_SUCCESS; }
void occQt::makeChamfer() { gp_Ax2 anAxis; anAxis.SetLocation(gp_Pnt(8.0, 50.0, 0.0)); TopoDS_Shape aTopoBox = BRepPrimAPI_MakeBox(anAxis, 3.0, 4.0, 5.0); BRepFilletAPI_MakeChamfer MC(aTopoBox); TopTools_IndexedDataMapOfShapeListOfShape aEdgeFaceMap; TopExp::MapShapesAndAncestors(aTopoBox, TopAbs_EDGE, TopAbs_FACE, aEdgeFaceMap); for (Standard_Integer i = 1; i <= aEdgeFaceMap.Extent(); ++i) { TopoDS_Edge anEdge = TopoDS::Edge(aEdgeFaceMap.FindKey(i)); TopoDS_Face aFace = TopoDS::Face(aEdgeFaceMap.FindFromIndex(i).First()); MC.Add(0.6, 0.6, anEdge, aFace); } Handle_AIS_Shape anAisShape = new AIS_Shape(MC.Shape()); anAisShape->SetColor(Quantity_NOC_TOMATO); mContext->Display(anAisShape); }
//======================================================================= //function : Execute //purpose : //======================================================================= Standard_Integer GEOMImpl_ChamferDriver::Execute(TFunction_Logbook& log) const { if (Label().IsNull()) return 0; Handle(GEOM_Function) aFunction = GEOM_Function::GetFunction(Label()); GEOMImpl_IChamfer aCI (aFunction); Standard_Integer aType = aFunction->GetType(); TopoDS_Shape aShape; Handle(GEOM_Function) aRefShape = aCI.GetShape(); TopoDS_Shape aShapeBase = aRefShape->GetValue(); // Check the shape type. It have to be shell // or solid, or compsolid, or compound of these shapes. if (!isGoodForChamfer(aShapeBase)) { StdFail_NotDone::Raise ("Wrong shape. Must be shell or solid, or compsolid or compound of these shapes"); } BRepFilletAPI_MakeChamfer fill (aShapeBase); if (aType == CHAMFER_SHAPE_ALL) { // symmetric chamfer on all edges double aD = aCI.GetD(); TopTools_IndexedDataMapOfShapeListOfShape M; GEOMImpl_Block6Explorer::MapShapesAndAncestors(aShapeBase, TopAbs_EDGE, TopAbs_FACE, M); for (int i = 1; i <= M.Extent(); i++) { TopoDS_Edge E = TopoDS::Edge(M.FindKey(i)); TopoDS_Face F = TopoDS::Face(M.FindFromIndex(i).First()); if (!BRepTools::IsReallyClosed(E, F) && !BRep_Tool::Degenerated(E) && M.FindFromIndex(i).Extent() == 2) fill.Add(aD, E, F); } } else if (aType == CHAMFER_SHAPE_EDGE || aType == CHAMFER_SHAPE_EDGE_AD) { // chamfer on edges, common to two faces, with D1 on the first face TopoDS_Shape aFace1, aFace2; if (GEOMImpl_ILocalOperations::GetSubShape(aShapeBase, aCI.GetFace1(), aFace1) && GEOMImpl_ILocalOperations::GetSubShape(aShapeBase, aCI.GetFace2(), aFace2)) { TopoDS_Face F = TopoDS::Face(aFace1); // fill map of edges of the second face TopTools_MapOfShape aMap; TopExp_Explorer Exp2 (aFace2, TopAbs_EDGE); for (; Exp2.More(); Exp2.Next()) { aMap.Add(Exp2.Current()); } // find edges of the first face, common with the second face TopExp_Explorer Exp (aFace1, TopAbs_EDGE); for (; Exp.More(); Exp.Next()) { if (aMap.Contains(Exp.Current())) { TopoDS_Edge E = TopoDS::Edge(Exp.Current()); if (!BRepTools::IsReallyClosed(E, F) && !BRep_Tool::Degenerated(E)) { if ( aType == CHAMFER_SHAPE_EDGE ) { double aD1 = aCI.GetD1(); double aD2 = aCI.GetD2(); fill.Add(aD1, aD2, E, F); } else { double aD = aCI.GetD(); double anAngle = aCI.GetAngle(); if ( (anAngle > 0) && (anAngle < (M_PI/2.)) ) fill.AddDA(aD, anAngle, E, F); } } } } } } else if (aType == CHAMFER_SHAPE_FACES || aType == CHAMFER_SHAPE_FACES_AD) { // chamfer on all edges of the selected faces, with D1 on the selected face // (on first selected face, if the edge belongs to two selected faces) int aLen = aCI.GetLength(); int ind = 1; TopTools_MapOfShape aMap; TopTools_IndexedDataMapOfShapeListOfShape M; GEOMImpl_Block6Explorer::MapShapesAndAncestors(aShapeBase, TopAbs_EDGE, TopAbs_FACE, M); for (; ind <= aLen; ind++) { TopoDS_Shape aShapeFace; if (GEOMImpl_ILocalOperations::GetSubShape(aShapeBase, aCI.GetFace(ind), aShapeFace)) { TopoDS_Face F = TopoDS::Face(aShapeFace); TopExp_Explorer Exp (F, TopAbs_EDGE); for (; Exp.More(); Exp.Next()) { if (!aMap.Contains(Exp.Current())) { TopoDS_Edge E = TopoDS::Edge(Exp.Current()); if (!BRepTools::IsReallyClosed(E, F) && !BRep_Tool::Degenerated(E) && M.FindFromKey(E).Extent() == 2) { if (aType == CHAMFER_SHAPE_FACES) { double aD1 = aCI.GetD1(); double aD2 = aCI.GetD2(); fill.Add(aD1, aD2, E, F); } else { double aD = aCI.GetD(); double anAngle = aCI.GetAngle(); if ( (anAngle > 0) && (anAngle < (M_PI/2.)) ) fill.AddDA(aD, anAngle, E, F); } } } } } } } else if (aType == CHAMFER_SHAPE_EDGES || aType == CHAMFER_SHAPE_EDGES_AD) { // chamfer on selected edges with lenght param D1 & D2. int aLen = aCI.GetLength(); int ind = 1; TopTools_MapOfShape aMap; TopTools_IndexedDataMapOfShapeListOfShape M; GEOMImpl_Block6Explorer::MapShapesAndAncestors(aShapeBase, TopAbs_EDGE, TopAbs_FACE, M); for (; ind <= aLen; ind++) { TopoDS_Shape aShapeEdge; if (GEOMImpl_ILocalOperations::GetSubShape(aShapeBase, aCI.GetEdge(ind), aShapeEdge)) { TopoDS_Edge E = TopoDS::Edge(aShapeEdge); const TopTools_ListOfShape& aFacesList = M.FindFromKey(E); TopoDS_Face F = TopoDS::Face( aFacesList.First() ); if (aType == CHAMFER_SHAPE_EDGES) { double aD1 = aCI.GetD1(); double aD2 = aCI.GetD2(); fill.Add(aD1, aD2, E, F); } else { double aD = aCI.GetD(); double anAngle = aCI.GetAngle(); if ( (anAngle > 0) && (anAngle < (M_PI/2.)) ) fill.AddDA(aD, anAngle, E, F); } } } } else { } fill.Build(); if (!fill.IsDone()) { StdFail_NotDone::Raise("Chamfer can not be computed on the given shape with the given parameters"); } aShape = fill.Shape(); if (aShape.IsNull()) return 0; // reduce tolerances ShapeFix_ShapeTolerance aSFT; aSFT.LimitTolerance(aShape, Precision::Confusion(), Precision::Confusion(), TopAbs_SHAPE); Handle(ShapeFix_Shape) aSfs = new ShapeFix_Shape(aShape); aSfs->Perform(); aShape = aSfs->Shape(); // fix SameParameter flag BRepLib::SameParameter(aShape, 1.E-5, Standard_True); aFunction->SetValue(aShape); log.SetTouched(Label()); return 1; }
//======================================================================= //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; }
//======================================================================= //function : PerformLoops //purpose : //======================================================================= void GEOMAlgo_BuilderFace::PerformLoops() { myErrorStatus=0; // Standard_Boolean bFlag; Standard_Integer aNbEA; TopTools_ListIteratorOfListOfShape aIt; TopTools_MapIteratorOfMapOfOrientedShape aItM; TopTools_IndexedDataMapOfShapeListOfShape aVEMap; TopTools_MapOfOrientedShape aMAdded; TopoDS_Iterator aItW; BRep_Builder aBB; GEOMAlgo_WireEdgeSet aWES; GEOMAlgo_WESCorrector aWESCor; // // 1. Usual Wires myLoops.Clear(); aWES.SetFace(myFace); // aIt.Initialize (myShapes); for (; aIt.More(); aIt.Next()) { const TopoDS_Shape& aE=aIt.Value(); if (!myShapesToAvoid.Contains(aE)) { aWES.AddStartElement(aE); } } // aWESCor.SetWES(aWES); aWESCor.Perform(); // GEOMAlgo_WireEdgeSet& aWESN=aWESCor.NewWES(); const TopTools_ListOfShape& aLW=aWESN.Shapes(); // aIt.Initialize (aLW); for (; aIt.More(); aIt.Next()) { const TopoDS_Shape& aW=aIt.Value(); myLoops.Append(aW); } //modified by NIZNHY-PKV Tue Aug 5 15:09:29 2008f // Post Treatment TopTools_MapOfOrientedShape aMEP; // // a. collect all edges that are in loops aIt.Initialize (myLoops); for (; aIt.More(); aIt.Next()) { const TopoDS_Shape& aW=aIt.Value(); aItW.Initialize(aW); for (; aItW.More(); aItW.Next()) { const TopoDS_Shape& aE=aItW.Value(); aMEP.Add(aE); } } // // b. collect all edges that are to avoid aItM.Initialize(myShapesToAvoid); for (; aItM.More(); aItM.Next()) { const TopoDS_Shape& aE=aItM.Key(); aMEP.Add(aE); } // // c. add all edges that are not processed to myShapesToAvoid aIt.Initialize (myShapes); for (; aIt.More(); aIt.Next()) { const TopoDS_Shape& aE=aIt.Value(); if (!aMEP.Contains(aE)) { myShapesToAvoid.Add(aE); } } //modified by NIZNHY-PKV Tue Aug 5 15:09:35 2008t // // 2. Internal Wires myLoopsInternal.Clear(); // aNbEA=myShapesToAvoid.Extent(); aItM.Initialize(myShapesToAvoid); for (; aItM.More(); aItM.Next()) { const TopoDS_Shape& aEE=aItM.Key(); TopExp::MapShapesAndAncestors(aEE, TopAbs_VERTEX, TopAbs_EDGE, aVEMap); } // bFlag=Standard_True; aItM.Initialize(myShapesToAvoid); for (; aItM.More()&&bFlag; aItM.Next()) { const TopoDS_Shape& aEE=aItM.Key(); if (!aMAdded.Add(aEE)) { continue; } // // make new wire TopoDS_Wire aW; aBB.MakeWire(aW); aBB.Add(aW, aEE); // aItW.Initialize(aW); for (; aItW.More()&&bFlag; aItW.Next()) { const TopoDS_Edge& aE=TopoDS::Edge(aItW.Value()); // TopoDS_Iterator aItE(aE); for (; aItE.More()&&bFlag; aItE.Next()) { const TopoDS_Vertex& aV = TopoDS::Vertex(aItE.Value()); const TopTools_ListOfShape& aLE=aVEMap.FindFromKey(aV); aIt.Initialize(aLE); for (; aIt.More()&&bFlag; aIt.Next()) { const TopoDS_Shape& aEx=aIt.Value(); if (aMAdded.Add(aEx)) { aBB.Add(aW, aEx); if(aMAdded.Extent()==aNbEA) { bFlag=!bFlag; } } }//for (; aIt.More(); aIt.Next()) { }//for (; aItE.More(); aItE.Next()) { }//for (; aItW.More(); aItW.Next()) { myLoopsInternal.Append(aW); }//for (; aItM.More(); aItM.Next()) { }
App::DocumentObjectExecReturn *Chamfer::execute(void) { // NOTE: Normally the Base property and the BaseFeature property should point to the same object. // The only difference is that the Base property also stores the edges that are to be chamfered Part::TopoShape TopShape; try { TopShape = getBaseShape(); } catch (Base::Exception& e) { return new App::DocumentObjectExecReturn(e.what()); } std::vector<std::string> SubNames = std::vector<std::string>(Base.getSubValues()); getContiniusEdges(TopShape, SubNames); if (SubNames.size() == 0) return new App::DocumentObjectExecReturn("No edges specified"); double size = Size.getValue(); if (size <= 0) return new App::DocumentObjectExecReturn("Size must be greater than zero"); this->positionByBaseFeature(); // create an untransformed copy of the basefeature shape Part::TopoShape baseShape(TopShape); baseShape.setTransform(Base::Matrix4D()); try { BRepFilletAPI_MakeChamfer mkChamfer(baseShape.getShape()); TopTools_IndexedMapOfShape mapOfEdges; TopTools_IndexedDataMapOfShapeListOfShape mapEdgeFace; TopExp::MapShapesAndAncestors(baseShape.getShape(), TopAbs_EDGE, TopAbs_FACE, mapEdgeFace); TopExp::MapShapes(baseShape.getShape(), TopAbs_EDGE, mapOfEdges); for (std::vector<std::string>::const_iterator it=SubNames.begin(); it != SubNames.end(); ++it) { TopoDS_Edge edge = TopoDS::Edge(baseShape.getSubShape(it->c_str())); const TopoDS_Face& face = TopoDS::Face(mapEdgeFace.FindFromKey(edge).First()); mkChamfer.Add(size, edge, face); } mkChamfer.Build(); if (!mkChamfer.IsDone()) return new App::DocumentObjectExecReturn("Failed to create chamfer"); TopoDS_Shape shape = mkChamfer.Shape(); if (shape.IsNull()) return new App::DocumentObjectExecReturn("Resulting shape is null"); TopTools_ListOfShape aLarg; aLarg.Append(baseShape.getShape()); if (!BRepAlgo::IsValid(aLarg, shape, Standard_False, Standard_False)) { ShapeFix_ShapeTolerance aSFT; aSFT.LimitTolerance(shape, Precision::Confusion(), Precision::Confusion(), TopAbs_SHAPE); Handle(ShapeFix_Shape) aSfs = new ShapeFix_Shape(shape); aSfs->Perform(); shape = aSfs->Shape(); if (!BRepAlgo::IsValid(aLarg, shape, Standard_False, Standard_False)) { return new App::DocumentObjectExecReturn("Resulting shape is invalid"); } } this->Shape.setValue(getSolid(shape)); return App::DocumentObject::StdReturn; } catch (Standard_Failure& e) { return new App::DocumentObjectExecReturn(e.GetMessageString()); } }
int OCCWire::chamfer(std::vector<OCCVertex *> vertices, std::vector<double> distances) { int vertices_size = vertices.size(); int distances_size = distances.size(); BRepFilletAPI_MakeFillet2d MF; try { if (this->getShape().IsNull()) { StdFail_NotDone::Raise("Shapes is Null"); } MF.Init(BRepBuilderAPI_MakeFace(this->getWire())); // creat map of vertices TopTools_IndexedMapOfShape vertMap; for (unsigned i=0; i<vertices.size(); i++) vertMap.Add(vertices[i]->getShape()); bool first = true; TopoDS_Edge firstEdge, nextEdge; TopoDS_Vertex vertex; BRepTools_WireExplorer Ex1; for (Ex1.Init(this->getWire()); Ex1.More(); ) { if(first == true) { firstEdge = Ex1.Current(); first = false; } Ex1.Next(); //if the number of edges is odd don't proceed if(Ex1.More() == Standard_False) break; nextEdge = Ex1.Current(); //get the common vertex of the two edges if (!TopExp::CommonVertex(firstEdge, nextEdge, vertex)) { // disconnected wire first = true; continue; } if (vertMap.Contains(vertex)) { int i = vertMap.FindIndex(vertex) - 1; if (distances_size == 1) { // single distance MF.AddChamfer(firstEdge, nextEdge, distances[0], distances[0]); } else if (distances_size == vertices_size) { // distance given for each vertex MF.AddChamfer(firstEdge, nextEdge, distances[i], distances[i]); } else { StdFail_NotDone::Raise("distances argument has wrong size"); } } firstEdge = nextEdge; } // special case for closed wire if (isClosed()) { // find seam vertex TopoDS_Vertex aV1; TopExp::Vertices(this->getWire(), vertex, aV1); // check if seam vertex has chamfer value if (vertMap.Contains(vertex)) { int i = vertMap.FindIndex(vertex) - 1; // map vertices to edges to find edge pair TopTools_IndexedDataMapOfShapeListOfShape mapVertexEdge; TopExp::MapShapesAndAncestors(this->getWire(), TopAbs_VERTEX, TopAbs_EDGE, mapVertexEdge); const TopTools_ListOfShape& edges = mapVertexEdge.FindFromKey(vertex); firstEdge = TopoDS::Edge(edges.First()); nextEdge = TopoDS::Edge(edges.Last()); if (distances_size == 1) { // single distance MF.AddChamfer(firstEdge, nextEdge, distances[0], distances[0]); } else if (distances_size == vertices_size) { // distance given for each vertex MF.AddChamfer(firstEdge, nextEdge, distances[i], distances[i]); } else { StdFail_NotDone::Raise("distances argument has wrong size"); } } } if(MF.Status() != ChFi2d_IsDone) StdFail_NotDone::Raise("chamfer operation failed"); TopTools_IndexedMapOfShape aMap; TopExp::MapShapes(MF.Shape(), TopAbs_WIRE, aMap); if(aMap.Extent() != 1) StdFail_NotDone::Raise("chamfer result did not result in single wire");; //add edges to the wire BRepBuilderAPI_MakeWire wire; BRepTools_WireExplorer Ex2; for(Ex2.Init(TopoDS::Wire(aMap(1))); Ex2.More(); Ex2.Next()) { wire.Add(Ex2.Current()); } this->setShape(wire.Shape()); // possible fix shape if (!this->fixShape()) StdFail_NotDone::Raise("Shapes not valid"); } catch(Standard_Failure &err) { Handle_Standard_Failure e = Standard_Failure::Caught(); const Standard_CString msg = e->GetMessageString(); if (msg != NULL && strlen(msg) > 1) { setErrorMessage(msg); } else { setErrorMessage("Failed to chamfer wire"); } return 0; } return 1; }
//======================================================================= //function : PerformInternalShapes //purpose : //======================================================================= void GEOMAlgo_BuilderFace::PerformInternalShapes() { myErrorStatus=0; // Standard_Integer aNbWI=myLoopsInternal.Extent(); if (!aNbWI) {// nothing to do return; } // //Standard_Real aTol; BRep_Builder aBB; TopTools_ListIteratorOfListOfShape aIt1, aIt2; TopoDS_Iterator aIt; TopTools_MapOfShape aME, aMEP; TopTools_MapIteratorOfMapOfShape aItME; TopTools_IndexedDataMapOfShapeListOfShape aMVE; TopTools_ListOfShape aLSI; // // 1. All internal edges aIt1.Initialize(myLoopsInternal); for (; aIt1.More(); aIt1.Next()) { const TopoDS_Shape& aWire=aIt1.Value(); aIt.Initialize(aWire); for (; aIt.More(); aIt.Next()) { const TopoDS_Shape& aE=aIt.Value(); aME.Add(aE); } } aNbWI=aME.Extent(); // // 2 Process faces aIt2.Initialize(myAreas); for ( ; aIt2.More(); aIt2.Next()) { TopoDS_Face& aF=TopoDS::Face(aIt2.Value()); // aMVE.Clear(); TopExp::MapShapesAndAncestors(aF, TopAbs_VERTEX, TopAbs_EDGE, aMVE); // // 2.1 Separate faces to process aMEP aMEP.Clear(); aItME.Initialize(aME); for (; aItME.More(); aItME.Next()) { const TopoDS_Edge& aE=TopoDS::Edge(aItME.Key()); if (IsInside(aE, aF, myContext)) { aMEP.Add(aE); } } // // 2.2 Make Internal Wires aLSI.Clear(); MakeInternalWires(aMEP, aLSI); // // 2.3 Add them to aF aIt1.Initialize(aLSI); for (; aIt1.More(); aIt1.Next()) { const TopoDS_Shape& aSI=aIt1.Value(); aBB.Add (aF, aSI); } // // 2.4 Remove faces aMFP from aMF aItME.Initialize(aMEP); for (; aItME.More(); aItME.Next()) { const TopoDS_Shape& aE=aItME.Key(); aME.Remove(aE); } // aNbWI=aME.Extent(); if (!aNbWI) { break; } } //for ( ; aIt2.More(); aIt2.Next()) { }
//======================================================================= //function : FillIn3DParts //purpose : //======================================================================= void GEOMAlgo_Builder::FillIn3DParts() { myErrorStatus=0; // const NMTDS_ShapesDataStructure& aDS=*myPaveFiller->DS(); NMTTools_PaveFiller* pPF=myPaveFiller; const Handle(IntTools_Context)& aCtx= pPF->Context(); // Standard_Boolean bIsIN, bHasImage; Standard_Integer aNbS, aNbSolids, i, j, aNbFaces, aNbFP, aNbFPx, aNbFIN, aNbLIF; TopAbs_ShapeEnum aType; TopAbs_State aState; TopTools_IndexedMapOfShape aMSolids, aMS, aMFaces, aMFIN; TopTools_MapOfShape aMFDone; TopTools_IndexedDataMapOfShapeListOfShape aMEF; TopTools_ListIteratorOfListOfShape aItS; TopoDS_Iterator aIt, aItF; BRep_Builder aBB; TopoDS_Solid aSolidSp; TopoDS_Face aFP; // myDraftSolids.Clear(); // aNbS=aDS.NumberOfShapesOfTheObject(); for (i=1; i<=aNbS; ++i) { const TopoDS_Shape& aS=aDS.Shape(i); // aType=aS.ShapeType(); if (aType==TopAbs_SOLID) { // all solids from DS aMSolids.Add(aS); } else if (aType==TopAbs_FACE) { // all faces (originals from DS or theirs images) if (myImages.HasImage(aS)) { const TopTools_ListOfShape& aLS=myImages.Image(aS); aItS.Initialize(aLS); for (; aItS.More(); aItS.Next()) { const TopoDS_Shape& aFx=aItS.Value(); // if (mySameDomainShapes.Contains(aFx)) { const TopoDS_Shape& aFSDx=mySameDomainShapes.FindFromKey(aFx); aMFaces.Add(aFSDx); } else { aMFaces.Add(aFx); } } } else { if (mySameDomainShapes.Contains(aS)) { const TopoDS_Shape& aFSDx=mySameDomainShapes.FindFromKey(aS); aMFaces.Add(aFSDx); } else { aMFaces.Add(aS); } } } } // aNbFaces=aMFaces.Extent(); aNbSolids=aMSolids.Extent(); // for (i=1; i<=aNbSolids; ++i) { const TopoDS_Solid& aSolid=TopoDS::Solid(aMSolids(i)); aMFDone.Clear(); aMFIN.Clear(); aMEF.Clear(); // aBB.MakeSolid(aSolidSp); // TopTools_ListOfShape aLIF; // BuildDraftSolid(aSolid, aSolidSp, aLIF); aNbLIF=aLIF.Extent(); // // 1 all faces/edges from aSolid [ aMS ] bHasImage=Standard_False; aMS.Clear(); aIt.Initialize(aSolid); for (; aIt.More(); aIt.Next()) { const TopoDS_Shape& aShell=aIt.Value(); // if (myImages.HasImage(aShell)) { bHasImage=Standard_True; // const TopTools_ListOfShape& aLS=myImages.Image(aShell); aItS.Initialize(aLS); for (; aItS.More(); aItS.Next()) { const TopoDS_Shape& aSx=aItS.Value(); aMS.Add(aSx); TopExp::MapShapes(aSx, TopAbs_FACE, aMS); TopExp::MapShapes(aSx, TopAbs_EDGE, aMS); TopExp::MapShapesAndAncestors(aSx, TopAbs_EDGE, TopAbs_FACE, aMEF); } } else { //aMS.Add(aShell); TopExp::MapShapes(aShell, TopAbs_FACE, aMS); //modified by NIZNHY-PKV Fri Dec 03 11:18:45 2010f TopExp::MapShapes(aShell, TopAbs_EDGE, aMS); //modified by NIZNHY-PKV Fri Dec 03 11:18:51 2010t TopExp::MapShapesAndAncestors(aShell, TopAbs_EDGE, TopAbs_FACE, aMEF); } } // // 2 all faces that are not from aSolid [ aLFP1 ] Standard_Integer aNbEFP; TopTools_IndexedDataMapOfShapeListOfShape aMEFP; TopTools_ListIteratorOfListOfShape aItFP, aItEx; TopTools_MapOfShape aMFence; TopTools_ListOfShape aLFP1, aLFP2, aLFP, aLCBF, aLFIN, aLEx;//*pLFP, // // for all non-solid faces build EF map [ aMEFP ] for (j=1; j<=aNbFaces; ++j) { const TopoDS_Shape& aFace=aMFaces(j); if (!aMS.Contains(aFace)) { TopExp::MapShapesAndAncestors(aFace, TopAbs_EDGE, TopAbs_FACE, aMEFP); } } // // among all faces from aMEFP select these that have same edges // with the solid (i.e aMEF). These faces will be treated first // to prevent the usage of 3D classifier. // The full list of faces to process is aLFP1. aNbEFP=aMEFP.Extent(); for (j=1; j<=aNbEFP; ++j) { const TopoDS_Shape& aE=aMEFP.FindKey(j); // if (aMEF.Contains(aE)) { // !! const TopTools_ListOfShape& aLF=aMEFP(j); aItFP.Initialize(aLF); for (; aItFP.More(); aItFP.Next()) { const TopoDS_Shape& aF=aItFP.Value(); if (aMFence.Add(aF)) { aLFP1.Append(aF); } } } else { aLEx.Append(aE); } } // aItEx.Initialize(aLEx); for (; aItEx.More(); aItEx.Next()) { const TopoDS_Shape& aE=aItEx.Value(); const TopTools_ListOfShape& aLF=aMEFP.FindFromKey(aE); aItFP.Initialize(aLF); for (; aItFP.More(); aItFP.Next()) { const TopoDS_Shape& aF=aItFP.Value(); if (aMFence.Add(aF)) { aLFP2.Append(aF); } } } aLFP1.Append(aLFP2); //========== // // 3 Process faces aLFP1 aNbFP=aLFP1.Extent(); aItFP.Initialize(aLFP1); for (; aItFP.More(); aItFP.Next()) { const TopoDS_Shape& aSP=aItFP.Value(); if (!aMFDone.Add(aSP)) { continue; } // // first face to process aFP=TopoDS::Face(aSP); bIsIN= GEOMAlgo_Tools3D::IsInternalFace(aFP, aSolidSp, aMEF, 1.e-14, aCtx); aState=(bIsIN) ? TopAbs_IN : TopAbs_OUT; // // collect faces to process [ aFP is the first ] aLFP.Clear(); aLFP.Append(aFP); aItS.Initialize(aLFP1); for (; aItS.More(); aItS.Next()) { const TopoDS_Shape& aSk=aItS.Value(); if (!aMFDone.Contains(aSk)) { aLFP.Append(aSk); } } // // Connexity Block that spreads from aFP the Bound // or till the end of the block itself aLCBF.Clear(); GEOMAlgo_Tools3D::MakeConnexityBlock(aLFP, aMS, aLCBF); // // fill states for the Connexity Block aItS.Initialize(aLCBF); for (; aItS.More(); aItS.Next()) { const TopoDS_Shape& aSx=aItS.Value(); aMFDone.Add(aSx); if (aState==TopAbs_IN) { aMFIN.Add(aSx); } } // aNbFPx=aMFDone.Extent(); if (aNbFPx==aNbFP) { break; } }//for (; aItFP.More(); aItFP.Next()) // // faces Inside aSolid aLFIN.Clear(); aNbFIN=aMFIN.Extent(); if (aNbFIN || aNbLIF) { for (j=1; j<=aNbFIN; ++j) { const TopoDS_Shape& aFIN=aMFIN(j); aLFIN.Append(aFIN); } // aItS.Initialize(aLIF); for (; aItS.More(); aItS.Next()) { const TopoDS_Shape& aFIN=aItS.Value(); aLFIN.Append(aFIN); } // myInParts.Add(aSolid, aLFIN); } if (aNbFIN || bHasImage) { myDraftSolids.Add(aSolid, aSolidSp); } }//for (i=1; i<=aNbSolids; ++i) { // next solid }
//======================================================================= //function :FillInternalShapes //purpose : //======================================================================= void GEOMAlgo_Builder::FillInternalShapes() { myErrorStatus=0; // const NMTDS_ShapesDataStructure& aDS=*myPaveFiller->DS(); NMTTools_PaveFiller* pPF=myPaveFiller; const Handle(IntTools_Context)& aCtx= pPF->Context(); // //Standard_Boolean bHasImage; Standard_Integer i, j, jT, aNbS, aNbSI, aNbSx, aNbSd; TopAbs_ShapeEnum aType, aT[]={ TopAbs_VERTEX, TopAbs_EDGE }; TopAbs_State aState; TopTools_ListIteratorOfListOfShape aIt, aIt1; TopTools_IndexedDataMapOfShapeListOfShape aMSx; TopTools_IndexedMapOfShape aMx; TopTools_MapOfShape aMSI, aMFence, aMSOr; TopTools_MapIteratorOfMapOfShape aItM; TopTools_ListOfShape aLSI, aLSd; TopoDS_Iterator aItS; BRep_Builder aBB; // // 1. Shapes to process // // 1.1 Shapes from pure arguments aMSI // 1.1.1 vertex, edge for (i=0; i<2; ++i) { jT=(Standard_Integer)aT[i]; const TopTools_ListOfShape &aLS=myShapes1[jT]; aIt.Initialize(aLS); for (; aIt.More(); aIt.Next()) { const TopoDS_Shape& aS=aIt.Value(); if (aMFence.Add(aS)) { aLSI.Append(aS); } } } // 1.1.2 wire { jT=(Standard_Integer)TopAbs_WIRE; const TopTools_ListOfShape &aLW=myShapes1[jT]; aIt.Initialize(aLW); for (; aIt.More(); aIt.Next()) { const TopoDS_Shape& aW=aIt.Value(); aItS.Initialize(aW); for (; aItS.More(); aItS.Next()) { const TopoDS_Shape& aE=aItS.Value(); if (aMFence.Add(aE)) { aLSI.Append(aE); } } } } // 1.1.3 theirs images/sources aIt1.Initialize(aLSI); for (; aIt1.More(); aIt1.Next()) { const TopoDS_Shape& aS=aIt1.Value(); if (myImages.HasImage(aS)) { const TopTools_ListOfShape &aLSp=myImages.Image(aS); aIt.Initialize(aLSp); for (; aIt.More(); aIt.Next()) { const TopoDS_Shape& aSI=aIt.Value(); aMSI.Add(aSI); } } else { aMSI.Add(aS); } } aLSI.Clear(); aNbSI=aMSI.Extent(); // // 2. Internal vertices, edges from source solids aMFence.Clear(); aLSd.Clear(); // aNbS=aDS.NumberOfShapesOfTheObject(); for (i=1; i<=aNbS; ++i) { const TopoDS_Shape& aS=aDS.Shape(i); aType=aS.ShapeType(); if (aType==TopAbs_SOLID) { // aMx.Clear(); OwnInternalShapes(aS, aMx); // aNbSx=aMx.Extent(); for (j=1; j<=aNbSx; ++j) { const TopoDS_Shape& aSI=aMx(j); if (myImages.HasImage(aSI)) { const TopTools_ListOfShape &aLSp=myImages.Image(aSI); aIt.Initialize(aLSp); for (; aIt.More(); aIt.Next()) { const TopoDS_Shape& aSp=aIt.Value(); aMSI.Add(aSp); } } else { aMSI.Add(aSI); } } // // build aux map from splits of solids if (myImages.HasImage(aS)) { const TopTools_ListOfShape &aLSp=myImages.Image(aS); aIt.Initialize(aLSp); for (; aIt.More(); aIt.Next()) { const TopoDS_Shape& aSp=aIt.Value(); if (aMFence.Add(aSp)) { TopExp::MapShapesAndAncestors(aSp, TopAbs_VERTEX, TopAbs_EDGE, aMSx); TopExp::MapShapesAndAncestors(aSp, TopAbs_VERTEX, TopAbs_FACE, aMSx); TopExp::MapShapesAndAncestors(aSp, TopAbs_EDGE , TopAbs_FACE, aMSx); aLSd.Append(aSp); } } } else { if (aMFence.Add(aS)) { TopExp::MapShapesAndAncestors(aS, TopAbs_VERTEX, TopAbs_EDGE, aMSx); TopExp::MapShapesAndAncestors(aS, TopAbs_VERTEX, TopAbs_FACE, aMSx); TopExp::MapShapesAndAncestors(aS, TopAbs_EDGE , TopAbs_FACE, aMSx); aLSd.Append(aS); aMSOr.Add(aS); } } }//if (aType==TopAbs_SOLID) } // aNbSd=aLSd.Extent(); // // 3. Some shapes of aMSI can be already tied with faces of // split solids aItM.Initialize(aMSI); for (; aItM.More(); aItM.Next()) { const TopoDS_Shape& aSI=aItM.Key(); if (aMSx.Contains(aSI)) { const TopTools_ListOfShape &aLSx=aMSx.FindFromKey(aSI); aNbSx=aLSx.Extent(); if (aNbSx) { aMSI.Remove(aSI); } } } // // 4. Just check it aNbSI=aMSI.Extent(); if (!aNbSI) { return; } // // 5 Settle internal vertices and edges into solids aMx.Clear(); aIt.Initialize(aLSd); for (; aIt.More(); aIt.Next()) { TopoDS_Solid aSd=TopoDS::Solid(aIt.Value()); // aItM.Initialize(aMSI); for (; aItM.More(); aItM.Next()) { TopoDS_Shape aSI=aItM.Key(); aSI.Orientation(TopAbs_INTERNAL); // aState=GEOMAlgo_Tools3D::ComputeStateByOnePoint(aSI, aSd, 1.e-11, aCtx); if (aState==TopAbs_IN) { // if(aMSOr.Contains(aSd)) { // TopoDS_Solid aSdx; // aBB.MakeSolid(aSdx); aItS.Initialize(aSd); for (; aItS.More(); aItS.Next()) { const TopoDS_Shape& aSh=aItS.Value(); aBB.Add(aSdx, aSh); } // aBB.Add(aSdx, aSI); // myImages.Bind(aSd, aSdx); aMSOr.Remove(aSd); aSd=aSdx; } else { aBB.Add(aSd, aSI); } // aMSI.Remove(aSI); } //if (aState==TopAbs_IN) { }// for (; aItM.More(); aItM.Next()) { }//for (; aIt1.More(); aIt1.Next()) { }
//======================================================================= //function : DetectSolids //purpose : //======================================================================= void GEOMAlgo_GlueAnalyser::DetectSolids() { myErrorStatus=0; // Standard_Integer i, aNbF, aNbS, aNbC, aNbX; TopoDS_Compound aCmp; BRep_Builder aBB; TopTools_IndexedDataMapOfShapeListOfShape aMFS; TopTools_IndexedMapOfShape aMx, aMS; TopTools_DataMapIteratorOfDataMapOfShapeListOfShape aItIm; GEOMAlgo_CoupleOfShapes aCS; // GEOMAlgo_IndexedDataMapOfPassKeyShapeListOfShape aMPKLS; GEOMAlgo_PassKeyShape aPKSx; // aBB.MakeCompound(aCmp); // TopExp::MapShapesAndAncestors(myShape, TopAbs_FACE, TopAbs_SOLID, aMFS); // aItIm.Initialize(myImages); for (; aItIm.More(); aItIm.Next()) { const TopoDS_Shape& aIm=aItIm.Key(); if (aIm.ShapeType()!=TopAbs_FACE) { continue; } // const TopTools_ListOfShape& aLF=aItIm.Value(); aNbF=aLF.Extent(); if (aNbF!=2) { continue; } // TopoDS_Shape aSx[2], aFx[2]; // aFx[0]=aLF.First(); aFx[1]=aLF.Last(); for (i=0; i<2; ++i) { if (!aMFS.Contains(aFx[i])) { continue;// it must not be so } // const TopTools_ListOfShape& aLS=aMFS.FindFromKey(aFx[i]); aNbS=aLS.Extent(); if (aNbS!=1) { continue; } aSx[i]=aLS.First(); } // if (aSx[0].IsNull() || aSx[1].IsNull()) { continue; } // //aPKSx.Clear();//qft //qf //aPKSx.SetIds(aSx[0], aSx[1]); aPKSx.SetShapes(aSx[0], aSx[1]); //qt // if (!aMPKLS.Contains(aPKSx)) { TopTools_ListOfShape aLSx; // aLSx.Append(aSx[0]); aLSx.Append(aSx[1]); // aMPKLS.Add(aPKSx, aLSx); } } // mySolidsToGlue.Clear(); mySolidsAlone.Clear(); // aNbC=aMPKLS.Extent(); if (!aNbC) { return; } // for (i=1; i<=aNbC; ++i) { const TopTools_ListOfShape& aLSx=aMPKLS(i); const TopoDS_Shape& aSx1=aLSx.First(); const TopoDS_Shape& aSx2=aLSx.Last(); aCS.SetShape1(aSx1); aCS.SetShape2(aSx2); mySolidsToGlue.Append(aCS); // if (!aMx.Contains(aSx1)) { aBB.Add(aCmp, aSx1); aMx.Add(aSx1); } if (!aMx.Contains(aSx2)) { aBB.Add(aCmp, aSx2); aMx.Add(aSx2); } } myResult=aCmp; // // check alone solids TopExp::MapShapes(myShape, TopAbs_SOLID, aMS); // aNbX=aMx.Extent(); for (i=1; i<=aNbX; ++i) { const TopoDS_Shape& aSx=aMx(i); if (!aMS.Contains(aSx)) { mySolidsAlone.Append(aSx); } } }
//======================================================================= //function :PerformShapesToAvoid //purpose : //======================================================================= void GEOMAlgo_BuilderFace::PerformShapesToAvoid() { Standard_Boolean bFound; Standard_Integer i, iCnt, aNbV, aNbE; TopTools_IndexedDataMapOfShapeListOfShape aMVE; TopTools_ListIteratorOfListOfShape aIt; // myShapesToAvoid.Clear(); // iCnt=0; while (1) { ++iCnt; bFound=Standard_False; // // 1. MEF aMVE.Clear(); aIt.Initialize (myShapes); for (; aIt.More(); aIt.Next()) { const TopoDS_Shape& aE=aIt.Value(); if (!myShapesToAvoid.Contains(aE)) { TopExp::MapShapesAndAncestors(aE, TopAbs_VERTEX, TopAbs_EDGE, aMVE); } // else { // int a=0; // } } aNbV=aMVE.Extent(); // // 2. myEdgesToAvoid for (i=1; i<=aNbV; ++i) { const TopoDS_Vertex& aV=TopoDS::Vertex(aMVE.FindKey(i)); // TopTools_ListOfShape& aLE=aMVE.ChangeFromKey(aV); aNbE=aLE.Extent(); if (!aNbE) { continue; } // const TopoDS_Edge& aE1=TopoDS::Edge(aLE.First()); if (aNbE==1) { if (BRep_Tool::Degenerated(aE1)) { continue; } if (aV.Orientation()==TopAbs_INTERNAL) { continue; } bFound=Standard_True; myShapesToAvoid.Add(aE1); } else if (aNbE==2) { const TopoDS_Edge& aE2=TopoDS::Edge(aLE.Last()); if (aE2.IsSame(aE1)) { TopoDS_Vertex aV1x, aV2x; // TopExp::Vertices(aE1, aV1x, aV2x); if (aV1x.IsSame(aV2x)) { continue; } bFound=Standard_True; myShapesToAvoid.Add(aE1); myShapesToAvoid.Add(aE2); } } }// for (i=1; i<=aNbE; ++i) { // if (!bFound) { break; } // }//while (1) //printf(" EdgesToAvoid=%d, iCnt=%d\n", EdgesToAvoid.Extent(), iCnt); }
//======================================================================= //function : Execute //purpose : //======================================================================= Standard_Integer GEOMImpl_ScaleDriver::Execute(TFunction_Logbook& log) const { if (Label().IsNull()) return 0; Handle(GEOM_Function) aFunction = GEOM_Function::GetFunction(Label()); GEOMImpl_IScale aCI (aFunction); Standard_Integer aType = aFunction->GetType(); TopoDS_Shape aShape; if (aType == SCALE_SHAPE || aType == SCALE_SHAPE_COPY) { Handle(GEOM_Function) aRefShape = aCI.GetShape(); TopoDS_Shape aShapeBase = aRefShape->GetValue(); if (aShapeBase.IsNull()) return 0; gp_Pnt aP (0,0,0); Handle(GEOM_Function) aRefPoint = aCI.GetPoint(); if (!aRefPoint.IsNull()) { TopoDS_Shape aShapePnt = aRefPoint->GetValue(); if (aShapePnt.IsNull()) return 0; if (aShapePnt.ShapeType() != TopAbs_VERTEX) return 0; aP = BRep_Tool::Pnt(TopoDS::Vertex(aShapePnt)); } // Bug 6839: Check for standalone (not included in faces) degenerated edges TopTools_IndexedDataMapOfShapeListOfShape aEFMap; TopExp::MapShapesAndAncestors(aShapeBase, 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(aP, aCI.GetFactor()); BRepBuilderAPI_Transform aBRepTrsf (aShapeBase, aTrsf, Standard_False); aShape = aBRepTrsf.Shape(); } else if (aType == SCALE_SHAPE_AFFINE || aType == SCALE_SHAPE_AFFINE_COPY) { Handle(GEOM_Function) aRefShape = aCI.GetShape(); Handle(GEOM_Function) aRefVector = aCI.GetVector(); TopoDS_Shape aShapeBase = aRefShape->GetValue(); TopoDS_Shape aShapeVector = aRefVector->GetValue(); if (aShapeBase.IsNull() || aShapeVector.IsNull()) return 0; if (aShapeVector.ShapeType() != TopAbs_EDGE) return 0; TopoDS_Edge anEdgeVector = TopoDS::Edge(aShapeVector); // Bug 6839: Check for standalone (not included in faces) degenerated edges TopTools_IndexedDataMapOfShapeListOfShape aEFMap; TopExp::MapShapesAndAncestors(aShapeBase, 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"); } } //Get axis gp_Pnt aP1 = BRep_Tool::Pnt(TopExp::FirstVertex(anEdgeVector)); gp_Pnt aP2 = BRep_Tool::Pnt(TopExp::LastVertex(anEdgeVector)); gp_Dir aDir(gp_Vec(aP1, aP2)); gp_Ax2 anAx2(aP1, aDir); // Perform Scaling gp_GTrsf aGTrsf; aGTrsf.SetAffinity(anAx2, aCI.GetFactor()); BRepBuilderAPI_GTransform aBRepGTrsf(aShapeBase, aGTrsf, Standard_False); aShape = aBRepGTrsf.Shape(); } else if (aType == SCALE_SHAPE_AXES || aType == SCALE_SHAPE_AXES_COPY) { Handle(GEOM_Function) aRefShape = aCI.GetShape(); TopoDS_Shape aShapeBase = aRefShape->GetValue(); if (aShapeBase.IsNull()) return 0; bool isP = false; gp_Pnt aP (0,0,0); Handle(GEOM_Function) aRefPoint = aCI.GetPoint(); if (!aRefPoint.IsNull()) { TopoDS_Shape aShapePnt = aRefPoint->GetValue(); if (aShapePnt.IsNull()) return 0; if (aShapePnt.ShapeType() != TopAbs_VERTEX) return 0; aP = BRep_Tool::Pnt(TopoDS::Vertex(aShapePnt)); isP = true; } // Bug 6839: Check for standalone (not included in faces) degenerated edges TopTools_IndexedDataMapOfShapeListOfShape aEFMap; TopExp::MapShapesAndAncestors(aShapeBase, 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_GTrsf aGTrsf; gp_Mat rot (aCI.GetFactorX(), 0, 0, 0, aCI.GetFactorY(), 0, 0, 0, aCI.GetFactorZ()); aGTrsf.SetVectorialPart(rot); if (isP) { gp_Pnt anO (0,0,0); if (anO.Distance(aP) > Precision::Confusion()) { gp_GTrsf aGTrsfP0; aGTrsfP0.SetTranslationPart(anO.XYZ() - aP.XYZ()); gp_GTrsf aGTrsf0P; aGTrsf0P.SetTranslationPart(aP.XYZ()); //aGTrsf = aGTrsf0P * aGTrsf * aGTrsfP0; aGTrsf = aGTrsf0P.Multiplied(aGTrsf); aGTrsf = aGTrsf.Multiplied(aGTrsfP0); } } BRepBuilderAPI_GTransform aBRepGTrsf (aShapeBase, aGTrsf, Standard_False); if (!aBRepGTrsf.IsDone()) Standard_ConstructionError::Raise("Scaling not done"); aShape = aBRepGTrsf.Shape(); } else { } if (aShape.IsNull()) return 0; // Check shape validity BRepCheck_Analyzer ana (aShape, false); if (!ana.IsValid()) { ShapeFix_ShapeTolerance aSFT; aSFT.LimitTolerance(aShape,Precision::Confusion(),Precision::Confusion()); Handle(ShapeFix_Shape) aSfs = new ShapeFix_Shape(aShape); aSfs->SetPrecision(Precision::Confusion()); aSfs->Perform(); aShape = aSfs->Shape(); ana.Init(aShape, Standard_False); if (!ana.IsValid()) { Standard_CString anErrStr("Scaling aborted : non valid shape result"); #ifdef THROW_ON_INVALID_SH Standard_ConstructionError::Raise(anErrStr); #else MESSAGE(anErrStr); //further processing can be performed here //... //in case of failure of automatic treatment //mark the corresponding GEOM_Object as problematic TDF_Label aLabel = aFunction->GetOwnerEntry(); if (!aLabel.IsRoot()) { Handle(GEOM_Object) aMainObj = GEOM_Object::GetObject(aLabel); if (!aMainObj.IsNull()) aMainObj->SetDirty(Standard_True); } #endif } } aFunction->SetValue(aShape); log.SetTouched(Label()); return 1; }
//======================================================================= // function: MakeConnexityBlock. // purpose: //======================================================================= void GEOMAlgo_Tools3D::MakeConnexityBlock (const TopTools_ListOfShape& theLFIn, const TopTools_IndexedMapOfShape& theMEAvoid, TopTools_ListOfShape& theLCB) { Standard_Integer aNbF, aNbAdd1; TopExp_Explorer aExp; TopTools_IndexedDataMapOfShapeListOfShape aMEF; TopTools_MapIteratorOfMapOfShape aItM, aItM1; TopTools_MapOfShape aMCB, aMAdd, aMAdd1; TopTools_ListIteratorOfListOfShape aIt; // // 1. aMEF aNbF=theLFIn.Extent(); aIt.Initialize(theLFIn); for (; aIt.More(); aIt.Next()) { const TopoDS_Shape& aF=aIt.Value(); TopExp::MapShapesAndAncestors(aF, TopAbs_EDGE, TopAbs_FACE, aMEF); } // // 2. aMCB const TopoDS_Shape& aF1=theLFIn.First(); aMAdd.Add(aF1); // while(1) { aMAdd1.Clear(); aItM.Initialize(aMAdd); for (; aItM.More(); aItM.Next()) { const TopoDS_Shape& aF=aItM.Key(); // //aMAdd1.Clear(); aExp.Init(aF, TopAbs_EDGE); for (; aExp.More(); aExp.Next()) { const TopoDS_Shape& aE=aExp.Current(); if (theMEAvoid.Contains(aE)){ continue; } // const TopTools_ListOfShape& aLF=aMEF.FindFromKey(aE); aIt.Initialize(aLF); for (; aIt.More(); aIt.Next()) { const TopoDS_Shape& aFx=aIt.Value(); if (aFx.IsSame(aF)) { continue; } if (aMCB.Contains(aFx)) { continue; } aMAdd1.Add(aFx); } }//for (; aExp.More(); aExp.Next()){ aMCB.Add(aF); }// for (; aItM.More(); aItM.Next()) { // aNbAdd1=aMAdd1.Extent(); if (!aNbAdd1) { break; } // aMAdd.Clear(); aItM1.Initialize(aMAdd1); for (; aItM1.More(); aItM1.Next()) { const TopoDS_Shape& aFAdd=aItM1.Key(); aMAdd.Add(aFAdd); } // }//while(1) { // aNbF=aMCB.Extent(); aItM.Initialize(aMCB); for (; aItM.More(); aItM.Next()) { const TopoDS_Shape& aF=aItM.Key(); theLCB.Append(aF); } }
//======================================================================= //function : IsInternalFace //purpose : //======================================================================= Standard_Boolean GEOMAlgo_Tools3D::IsInternalFace(const TopoDS_Face& theFace, const TopoDS_Solid& theSolid, const TopTools_IndexedDataMapOfShapeListOfShape& theMEF, const Standard_Real theTol, IntTools_Context& theContext) { Standard_Boolean bRet; Standard_Integer aNbF; TopoDS_Edge aEL; TopExp_Explorer aExp; TopTools_ListIteratorOfListOfShape aItF; // bRet=Standard_False; // // 1 Try to find an edge from theFace in theMEF aExp.Init(theFace, TopAbs_EDGE); for(; aExp.More(); aExp.Next()) { const TopoDS_Edge& aE=TopoDS::Edge(aExp.Current()); if (!theMEF.Contains(aE)) { continue; } // const TopTools_ListOfShape& aLF=theMEF.FindFromKey(aE); aNbF=aLF.Extent(); if (!aNbF) { return bRet; // it can not be so } else if (aNbF==1) { // aE is internal edge on aLF.First() const TopoDS_Face& aF1=TopoDS::Face(aLF.First()); bRet=GEOMAlgo_Tools3D::IsInternalFace(theFace, aE, aF1, aF1, theContext); return bRet; } else if (aNbF==2) { const TopoDS_Face& aF1=TopoDS::Face(aLF.First()); const TopoDS_Face& aF2=TopoDS::Face(aLF.Last()); // if (aF2.IsSame(aF1) && BRep_Tool::IsClosed(aE, aF1)) { // treat as it was for 1 face bRet=GEOMAlgo_Tools3D::IsInternalFace(theFace, aE, aF1, aF2, theContext); return bRet; } } if (aNbF%2) { return bRet; // it can not be so } else { // aNbF=2,4,6,8,... bRet=GEOMAlgo_Tools3D::IsInternalFace(theFace, aE, aLF, theContext); return bRet; } }//for(; aExp.More(); aExp.Next()) { // //======================================== // 2. Classify face using classifier // TopAbs_State aState; TopTools_IndexedMapOfShape aBounds; // aState=GEOMAlgo_Tools3D::ComputeState(theFace, theSolid, theTol, aBounds, theContext); bRet=(aState==TopAbs_IN); // return bRet; }
//======================================================================= // function: Perform // purpose: //======================================================================= void GEOMAlgo_WireSplitter::Perform() { myErrorStatus=2; myNothingToDo=Standard_True; Standard_Integer index, i, aNb, aCntIn, aCntOut; Standard_Boolean anIsIn; Standard_Real anAngle; BOP_ListOfEdgeInfo emptyInfo; TopTools_ListIteratorOfListOfShape anItList; // // 1.Filling mySmartMap mySmartMap.Clear(); anItList.Initialize(myEdges); for (; anItList.More(); anItList.Next()) { const TopoDS_Edge& anEdge = TopoDS::Edge(anItList.Value()); // if (!BOPTools_Tools2D::HasCurveOnSurface (anEdge, myFace)) { continue; } // TopExp_Explorer anExpVerts (anEdge, TopAbs_VERTEX); for (; anExpVerts.More(); anExpVerts.Next()) { const TopoDS_Shape& aVertex= anExpVerts.Current(); index = mySmartMap.FindIndex(aVertex); if (!index) { index=mySmartMap.Add(aVertex, emptyInfo); } BOP_ListOfEdgeInfo& aListOfEInfo=mySmartMap(index); BOP_EdgeInfo aEInfo; aEInfo.SetEdge(anEdge); TopAbs_Orientation anOr=aVertex.Orientation(); if (anOr==TopAbs_FORWARD) { aEInfo.SetInFlag(Standard_False); } else if (anOr==TopAbs_REVERSED) { aEInfo.SetInFlag(Standard_True); } aListOfEInfo.Append(aEInfo); } } // aNb=mySmartMap.Extent(); // // 2. myNothingToDo myNothingToDo=Standard_True; for (i=1; i<=aNb; i++) { aCntIn=0; aCntOut=0; const BOP_ListOfEdgeInfo& aLEInfo= mySmartMap(i); BOP_ListIteratorOfListOfEdgeInfo anIt(aLEInfo); for (; anIt.More(); anIt.Next()) { const BOP_EdgeInfo& anEdgeInfo=anIt.Value(); anIsIn=anEdgeInfo.IsIn(); if (anIsIn) { aCntIn++; } else { aCntOut++; } } if (aCntIn!=1 || aCntOut!=1) { myNothingToDo=Standard_False; break; } } // // Each vertex has one edge In and one - Out. Good. But it is not enought // to consider that nothing to do with this. We must check edges on TShape // coinsidence. If there are such edges there is something to do with. // if (myNothingToDo) { Standard_Integer aNbE, aNbMapEE; TopTools_IndexedDataMapOfShapeListOfShape aMapEE; aNbE=myEdges.Extent(); anItList.Initialize(myEdges); for (; anItList.More(); anItList.Next()) { const TopoDS_Shape& aE = anItList.Value(); if (!aMapEE.Contains(aE)) { TopTools_ListOfShape aLEx; aLEx.Append(aE); aMapEE.Add(aE, aLEx); } else { TopTools_ListOfShape& aLEx=aMapEE.ChangeFromKey(aE); aLEx.Append(aE); } } Standard_Boolean bFlag; bFlag=Standard_True; aNbMapEE=aMapEE.Extent(); for (i=1; i<=aNbMapEE; i++) { const TopTools_ListOfShape& aLEx=aMapEE(i); aNbE=aLEx.Extent(); if (aNbE==1) { // usual case continue; } else if (aNbE==2){ const TopoDS_Shape& aE1=aLEx.First(); const TopoDS_Shape& aE2=aLEx.Last(); if (aE1.IsSame(aE2)) { bFlag=Standard_False; break; } } else { bFlag=Standard_False; break; } } myNothingToDo=myNothingToDo && bFlag; } // // if (myNothingToDo) { myErrorStatus=0; return; } // // 3. Angles in mySmartMap BRepAdaptor_Surface aBAS(myFace); const GeomAdaptor_Surface& aGAS=aBAS.Surface(); for (i=1; i<=aNb; i++) { const TopoDS_Vertex& aV=TopoDS::Vertex (mySmartMap.FindKey(i)); const BOP_ListOfEdgeInfo& aLEInfo= mySmartMap(i); BOP_ListIteratorOfListOfEdgeInfo anIt(aLEInfo); for (; anIt.More(); anIt.Next()) { BOP_EdgeInfo& anEdgeInfo=anIt.Value(); const TopoDS_Edge& aE=anEdgeInfo.Edge(); // TopoDS_Vertex aVV=aV; // anIsIn=anEdgeInfo.IsIn(); if (anIsIn) { // aVV.Orientation(TopAbs_REVERSED); anAngle=Angle2D (aVV, aE, myFace, aGAS, Standard_True); } // else { // OUT // aVV.Orientation(TopAbs_FORWARD); anAngle=Angle2D (aVV, aE, myFace, aGAS, Standard_False); } anEdgeInfo.SetAngle(anAngle); } } // // 4. Do // Standard_Boolean anIsOut, anIsNotPassed; TopTools_SequenceOfShape aLS, aVertVa; TColgp_SequenceOfPnt2d aCoordVa; BOP_ListIteratorOfListOfEdgeInfo anIt; for (i=1; i<=aNb; i++) { const TopoDS_Vertex aVa=TopoDS::Vertex (mySmartMap.FindKey(i)); const BOP_ListOfEdgeInfo& aLEInfo=mySmartMap(i); anIt.Initialize(aLEInfo); for (; anIt.More(); anIt.Next()) { BOP_EdgeInfo& anEdgeInfo=anIt.Value(); const TopoDS_Edge& aEOuta=anEdgeInfo.Edge(); anIsOut=!anEdgeInfo.IsIn(); anIsNotPassed=!anEdgeInfo.Passed(); if (anIsOut && anIsNotPassed) { // aLS.Clear(); aVertVa.Clear(); aCoordVa.Clear(); // Path(aGAS, myFace, aVa, aEOuta, anEdgeInfo, aLS, aVertVa, aCoordVa, myShapes, mySmartMap); } } } // { Standard_Integer aNbV, aNbE; TopoDS_Vertex aV1, aV2; BOPTColStd_ListOfListOfShape aShapes; BOPTColStd_ListIteratorOfListOfListOfShape anItW(myShapes); for (; anItW.More(); anItW.Next()) { TopTools_IndexedMapOfShape aMV, aME; const TopTools_ListOfShape& aLE=anItW.Value(); TopTools_ListIteratorOfListOfShape anItE(aLE); for (; anItE.More(); anItE.Next()) { const TopoDS_Edge& aE=TopoDS::Edge(anItE.Value()); aME.Add(aE); TopExp::Vertices(aE, aV1, aV2); aMV.Add(aV1); aMV.Add(aV2); } aNbV=aMV.Extent(); aNbE=aME.Extent(); if (aNbV<=aNbE) { aShapes.Append(aLE); } } // myShapes.Clear(); anItW.Initialize(aShapes); for (; anItW.More(); anItW.Next()) { const TopTools_ListOfShape& aLE=anItW.Value(); myShapes.Append(aLE); } } // myErrorStatus=0; }
//======================================================================= //function : Execute //purpose : //======================================================================= Standard_Integer GEOMImpl_ChamferDriver::Execute(TFunction_Logbook& log) const { if (Label().IsNull()) return 0; Handle(GEOM_Function) aFunction = GEOM_Function::GetFunction(Label()); GEOMImpl_IChamfer aCI (aFunction); Standard_Integer aType = aFunction->GetType(); TopoDS_Shape aShape; Handle(GEOM_Function) aRefShape = aCI.GetShape(); TopoDS_Shape aShapeBase = aRefShape->GetValue(); if (aType == CHAMFER_SHAPE_EDGES_2D) { BRepFilletAPI_MakeFillet2d fill; TopoDS_Face aFace; Standard_Boolean aWireFlag = Standard_False; if (aShapeBase.ShapeType() == TopAbs_FACE) aFace = TopoDS::Face(aShapeBase); else if (aShapeBase.ShapeType() == TopAbs_WIRE) { TopoDS_Wire aWire = TopoDS::Wire(aShapeBase); BRepBuilderAPI_MakeFace aMF(aWire); aMF.Build(); if (!aMF.IsDone()) { StdFail_NotDone::Raise("Cannot build initial face from given wire"); } aFace = aMF.Face(); aWireFlag = Standard_True; } else StdFail_NotDone::Raise("Base shape is neither a face or a wire !"); fill.Init(aFace); double aD1_2D = aCI.GetD1(); double aD2_2D = aCI.GetD2(); TopoDS_Shape aShapeFace1, aShapeFace2; if (GEOMImpl_ILocalOperations::GetSubShape(aShapeBase, aCI.Get2DEdge1(), aShapeFace1) && GEOMImpl_ILocalOperations::GetSubShape(aShapeBase, aCI.Get2DEdge2(), aShapeFace2)) { fill.AddChamfer(TopoDS::Edge(aShapeFace1), TopoDS::Edge(aShapeFace2), aD1_2D, aD2_2D); } else StdFail_NotDone::Raise("Cannot get 2d egde from sub-shape index!"); fill.Build(); if (!fill.IsDone()) { StdFail_NotDone::Raise("Chamfer can not be computed on the given shape with the given parameters"); } if (aWireFlag) { BRepBuilderAPI_MakeWire MW; TopExp_Explorer exp (fill.Shape(), TopAbs_EDGE); for (; exp.More(); exp.Next()) MW.Add(TopoDS::Edge(exp.Current())); MW.Build(); if (!MW.IsDone()) StdFail_NotDone::Raise("Resulting wire cannot be built"); aShape = MW.Shape(); } else aShape = fill.Shape(); } else { // Check the shape type. It have to be shell // or solid, or compsolid, or compound of these shapes. if (!isGoodForChamfer(aShapeBase)) { StdFail_NotDone::Raise ("Wrong shape. Must be shell or solid, or compsolid or compound of these shapes"); } BRepFilletAPI_MakeChamfer fill (aShapeBase); if (aType == CHAMFER_SHAPE_ALL) { // symmetric chamfer on all edges double aD = aCI.GetD(); TopTools_IndexedDataMapOfShapeListOfShape M; GEOMImpl_Block6Explorer::MapShapesAndAncestors(aShapeBase, TopAbs_EDGE, TopAbs_FACE, M); for (int i = 1; i <= M.Extent(); i++) { TopoDS_Edge E = TopoDS::Edge(M.FindKey(i)); TopoDS_Face F = TopoDS::Face(M.FindFromIndex(i).First()); if (!BRepTools::IsReallyClosed(E, F) && !BRep_Tool::Degenerated(E) && M.FindFromIndex(i).Extent() == 2) fill.Add(aD, E, F); } }else if (aType == CHAMFER_SHAPE_EDGE || aType == CHAMFER_SHAPE_EDGE_AD) { // chamfer on edges, common to two faces, with D1 on the first face TopoDS_Shape aFace1, aFace2; if (GEOMImpl_ILocalOperations::GetSubShape(aShapeBase, aCI.GetFace1(), aFace1) && GEOMImpl_ILocalOperations::GetSubShape(aShapeBase, aCI.GetFace2(), aFace2)) { TopoDS_Face F = TopoDS::Face(aFace1); // fill map of edges of the second face TopTools_MapOfShape aMap; TopExp_Explorer Exp2 (aFace2, TopAbs_EDGE); for (; Exp2.More(); Exp2.Next()) { aMap.Add(Exp2.Current()); } // find edges of the first face, common with the second face TopExp_Explorer Exp (aFace1, TopAbs_EDGE); for (; Exp.More(); Exp.Next()) { if (aMap.Contains(Exp.Current())) { TopoDS_Edge E = TopoDS::Edge(Exp.Current()); if (!BRepTools::IsReallyClosed(E, F) && !BRep_Tool::Degenerated(E)) { if ( aType == CHAMFER_SHAPE_EDGE ) { double aD1 = aCI.GetD1(); double aD2 = aCI.GetD2(); fill.Add(aD1, aD2, E, F); } else { double aD = aCI.GetD(); double anAngle = aCI.GetAngle(); if ( (anAngle > 0) && (anAngle < (Standard_PI/2)) ) fill.AddDA(aD, anAngle, E, F); } } } } } } else if (aType == CHAMFER_SHAPE_FACES || aType == CHAMFER_SHAPE_FACES_AD) { // chamfer on all edges of the selected faces, with D1 on the selected face // (on first selected face, if the edge belongs to two selected faces) int aLen = aCI.GetLength(); int ind = 1; TopTools_MapOfShape aMap; TopTools_IndexedDataMapOfShapeListOfShape M; GEOMImpl_Block6Explorer::MapShapesAndAncestors(aShapeBase, TopAbs_EDGE, TopAbs_FACE, M); for (; ind <= aLen; ind++) { TopoDS_Shape aShapeFace; if (GEOMImpl_ILocalOperations::GetSubShape(aShapeBase, aCI.GetFace(ind), aShapeFace)) { TopoDS_Face F = TopoDS::Face(aShapeFace); TopExp_Explorer Exp (F, TopAbs_EDGE); for (; Exp.More(); Exp.Next()) { if (!aMap.Contains(Exp.Current())) { TopoDS_Edge E = TopoDS::Edge(Exp.Current()); if (!BRepTools::IsReallyClosed(E, F) && !BRep_Tool::Degenerated(E) && M.FindFromKey(E).Extent() == 2) if (aType == CHAMFER_SHAPE_FACES) { double aD1 = aCI.GetD1(); double aD2 = aCI.GetD2(); fill.Add(aD1, aD2, E, F); } else { double aD = aCI.GetD(); double anAngle = aCI.GetAngle(); if ( (anAngle > 0) && (anAngle < (Standard_PI/2)) ) fill.AddDA(aD, anAngle, E, F); } } } } } } else if (aType == CHAMFER_SHAPE_EDGES || aType == CHAMFER_SHAPE_EDGES_AD) { // chamfer on selected edges with lenght param D1 & D2. int aLen = aCI.GetLength(); int ind = 1; TopTools_MapOfShape aMap; TopTools_IndexedDataMapOfShapeListOfShape M; GEOMImpl_Block6Explorer::MapShapesAndAncestors(aShapeBase, TopAbs_EDGE, TopAbs_FACE, M); for (; ind <= aLen; ind++) { TopoDS_Shape aShapeEdge; if (GEOMImpl_ILocalOperations::GetSubShape(aShapeBase, aCI.GetEdge(ind), aShapeEdge)) { TopoDS_Edge E = TopoDS::Edge(aShapeEdge); const TopTools_ListOfShape& aFacesList = M.FindFromKey(E); TopoDS_Face F = TopoDS::Face( aFacesList.First() ); if (aType == CHAMFER_SHAPE_EDGES) { double aD1 = aCI.GetD1(); double aD2 = aCI.GetD2(); fill.Add(aD1, aD2, E, F); } else { double aD = aCI.GetD(); double anAngle = aCI.GetAngle(); if ( (anAngle > 0) && (anAngle < (Standard_PI/2)) ) fill.AddDA(aD, anAngle, E, F); } } } } else { } fill.Build(); if (!fill.IsDone()) { StdFail_NotDone::Raise("Chamfer can not be computed on the given shape with the given parameters"); } aShape = fill.Shape(); } if (aShape.IsNull()) return 0; // Check shape validity BRepCheck_Analyzer ana (aShape, false); if (!ana.IsValid()) { // 08.07.2008 added by skl during fixing bug 19761 from Mantis ShapeFix_ShapeTolerance aSFT; aSFT.LimitTolerance(aShape, Precision::Confusion(), Precision::Confusion(), TopAbs_SHAPE); Handle(ShapeFix_Shape) aSfs = new ShapeFix_Shape(aShape); aSfs->Perform(); aShape = aSfs->Shape(); // fix SameParameter flag BRepLib::SameParameter(aShape, 1.E-5, Standard_True); ana.Init(aShape); if (!ana.IsValid()) { Standard_CString anErrStr("Chamfer algorithm has produced an invalid shape result"); #ifdef THROW_ON_INVALID_SH Standard_ConstructionError::Raise(anErrStr); #else MESSAGE(anErrStr); //further processing can be performed here //... //in case of failure of automatic treatment //mark the corresponding GEOM_Object as problematic TDF_Label aLabel = aFunction->GetOwnerEntry(); if (!aLabel.IsRoot()) { Handle(GEOM_Object) aMainObj = GEOM_Object::GetObject(aLabel); if (!aMainObj.IsNull()) aMainObj->SetDirty(Standard_True); } #endif } } aFunction->SetValue(aShape); log.SetTouched(Label()); return 1; }
//======================================================================= // function: FillInternalVertices // purpose: //======================================================================= void GEOMAlgo_Builder::FillInternalVertices() { const NMTDS_ShapesDataStructure& aDS=*myPaveFiller->DS(); NMTTools_PaveFiller* pPF=myPaveFiller; NMTDS_InterfPool* pIP=pPF->IP(); const Handle(IntTools_Context)& aCtx= pPF->Context(); // BOPTools_CArray1OfVSInterference& aVFs=pIP->VSInterferences(); BOPTools_CArray1OfESInterference& aEFs=pIP->ESInterferences(); const NMTTools_IndexedDataMapOfIndexedMapOfInteger& aMAV=pPF->AloneVertices(); // Standard_Boolean bHasImage; Standard_Integer i, j, nF, aNbS, nV, nVSD, n1, n2, iFlag; Standard_Integer aNbVFs, aNbAVF, aNbEFs, aNbVC, aNbE, aNbV; Standard_Real aU1, aU2, aTol; NMTTools_IndexedDataMapOfIndexedMapOfInteger aMFMV; TopTools_MapOfShape aMFence; TopTools_ListIteratorOfListOfShape aIt, aItV; BRep_Builder aBB; // // 1. Collect face-vertex candidates [aMFMV] // // 1.1. VFs aNbVFs=aVFs.Extent(); for (i=1; i<=aNbVFs; ++i) { const BOPTools_VSInterference& aVS=aVFs(i); aVS.Indices(n1, n2); nF=n2; nV=n1; if (aDS.Shape(n1).ShapeType()==TopAbs_FACE) { nF=n1; nV=n2; } nVSD=pPF->FindSDVertex(nV); if (nVSD) { nV=nVSD; } // UpdateCandidates(nF, nV, aMFMV); } // // 1.2 EFs aNbEFs=aEFs.Extent(); for (i=1; i<=aNbEFs; ++i) { const BOPTools_ESInterference& aEF=aEFs(i); aEF.Indices(n1, n2); nV=aEF.NewShape(); if (!nV) { continue; } const TopoDS_Shape& aSnew=aDS.Shape(nV); if (aSnew.ShapeType()!=TopAbs_VERTEX) { continue; } // nF=(aDS.Shape(n1).ShapeType()==TopAbs_FACE) ? n1 : n2; nVSD=pPF->FindSDVertex(nV); if (nVSD) { nV=nVSD; } UpdateCandidates(nF, nV, aMFMV); } // aNbS=aDS.NumberOfShapesOfTheObject(); for (nF=1; nF<=aNbS; ++nF) { const TopoDS_Shape& aF=aDS.Shape(nF); // if (aF.ShapeType()!=TopAbs_FACE) { continue; } if (!aMFence.Add(aF)) { continue; } // const TopoDS_Face& aFF=TopoDS::Face(aF); aTol=BRep_Tool::Tolerance(aFF); // // 1.3 FFs if (aMAV.Contains(nF)) { const TColStd_IndexedMapOfInteger& aMAVF=aMAV.FindFromKey(nF); aNbAVF=aMAVF.Extent(); for (j=1; j<=aNbAVF; ++j) { nV=aMAVF(j); nVSD=pPF->FindSDVertex(nV); if (nVSD) { nV=nVSD; } // UpdateCandidates(nF, nV, aMFMV); } } // // 1.4 Internal vertices of the face nF BooleanOperations_OnceExplorer aExp(aDS); aExp.Init(nF, TopAbs_VERTEX); for (; aExp.More(); aExp.Next()) { nV=aExp.Current(); const TopoDS_Shape& aV=aDS.Shape(nV); if (aV.Orientation()==TopAbs_INTERNAL) { nVSD=pPF->FindSDVertex(nV); if (nVSD) { nV=nVSD; } // UpdateCandidates(nF, nV, aMFMV); } } // // 2. Process face nF if (!aMFMV.Contains(nF)) { continue; } // const TColStd_IndexedMapOfInteger& aMVC=aMFMV.FindFromKey(nF); aNbVC=aMVC.Extent(); if (!aNbVC) { continue; } // // 2.1 Refine candidates TopTools_IndexedDataMapOfShapeListOfShape aMVE; TopTools_ListOfShape aLV; // bHasImage=myImages.HasImage(aF); if (bHasImage) { const TopTools_ListOfShape& aLFx=myImages.Image(aF); aIt.Initialize(aLFx); for (; aIt.More(); aIt.Next()) { const TopoDS_Shape& aFx=aIt.Value(); TopExp::MapShapesAndAncestors(aFx, TopAbs_VERTEX, TopAbs_EDGE, aMVE); } } else { Standard_Boolean bFaceToProcess; // TopExp::MapShapesAndAncestors(aF, TopAbs_VERTEX, TopAbs_EDGE, aMVE); bFaceToProcess=Standard_False; for (j=1; j<=aNbVC; ++j) { nV=aMVC(j); const TopoDS_Shape& aV=aDS.Shape(nV); if (!aMVE.Contains(aV)) { bFaceToProcess=!bFaceToProcess; break; } } if (!bFaceToProcess) { continue; } }// else // for (j=1; j<=aNbVC; ++j) { nV=aMVC(j); const TopoDS_Shape& aV=aDS.Shape(nV); if (aMVE.Contains(aV)) { const TopTools_ListOfShape& aLE=aMVE.FindFromKey(aV); aNbE=aLE.Extent(); if (aNbE) { continue; } } aLV.Append(aV); } // aNbV=aLV.Extent(); if (aNbV) { // 3. Try to put vertices into the face(s) aItV.Initialize(aLV); for (; aItV.More(); aItV.Next()) { TopoDS_Vertex aV=TopoDS::Vertex(aItV.Value()); aV.Orientation(TopAbs_INTERNAL); // bHasImage=myImages.HasImage(aF); if (bHasImage) { const TopTools_ListOfShape& aLFx=myImages.Image(aF); aIt.Initialize(aLFx); for (; aIt.More(); aIt.Next()) { TopoDS_Face aFx=TopoDS::Face(aIt.Value()); // update classifier IntTools_FClass2d& aClsf=aCtx->FClass2d(aFx); aClsf.Init(aFx, aTol); // iFlag=aCtx->ComputeVS (aV, aFx, aU1, aU2); if (!iFlag) { aBB.Add(aFx, aV); break; } } } else { const TopoDS_Face& aFx=TopoDS::Face(aF); // update classifier IntTools_FClass2d& aClsf=aCtx->FClass2d(aFx); aClsf.Init(aFx, aTol); // iFlag=aCtx->ComputeVS (aV, aFx, aU1, aU2); if (!iFlag) { TopoDS_Face aFz; // GEOMAlgo_Tools3D::CopyFace(aFx, aFz); aBB.Add(aFz, aV); myImages.Bind(aF, aFz); } } }// for (; aItV.More(); aItV.Next()) { }// if (aNbV) { }// for (nF=1; nF<=aNb; ++nF) { }
//======================================================================= //function : Execute //purpose : //======================================================================= Standard_Integer GEOMImpl_Fillet1dDriver::Execute(TFunction_Logbook& log) const { if (Label().IsNull()) return 0; Handle(GEOM_Function) aFunction = GEOM_Function::GetFunction(Label()); GEOMImpl_IFillet1d aCI (aFunction); Handle(GEOM_Function) aRefShape = aCI.GetShape(); TopoDS_Shape aShape = aRefShape->GetValue(); if (aShape.IsNull()) return 0; if (aShape.ShapeType() != TopAbs_WIRE) Standard_ConstructionError::Raise("Wrong arguments: polyline as wire must be given"); TopoDS_Wire aWire = TopoDS::Wire(aShape); double rad = aCI.GetR(); if ( rad < Precision::Confusion()) return 0; // collect vertices for make fillet TopTools_ListOfShape aVertexList; TopTools_MapOfShape mapShape; int aLen = aCI.GetLength(); if ( aLen > 0 ) { for (int ind = 1; ind <= aLen; ind++) { TopoDS_Shape aShapeVertex; if (GEOMImpl_ILocalOperations::GetSubShape (aWire, aCI.GetVertex(ind), aShapeVertex)) if (mapShape.Add(aShapeVertex)) aVertexList.Append( aShapeVertex ); } } else { // get all vertices from wire TopExp_Explorer anExp( aWire, TopAbs_VERTEX ); for ( ; anExp.More(); anExp.Next() ) { if (mapShape.Add(anExp.Current())) aVertexList.Append( anExp.Current() ); } } if (aVertexList.IsEmpty()) Standard_ConstructionError::Raise("Invalid input no vertices to make fillet"); //INFO: this algorithm implemented in assumption that user can select both // vertices of some edges to make fillet. In this case we should remember // already modified initial edges to take care in next fillet step TopTools_DataMapOfShapeShape anEdgeToEdgeMap; //iterates on vertices, and make fillet on each couple of edges //collect result fillet edges in list TopTools_ListOfShape aListOfNewEdge; // remember relation between initial and modified map TopTools_IndexedDataMapOfShapeListOfShape aMapVToEdges; TopExp::MapShapesAndAncestors( aWire, TopAbs_VERTEX, TopAbs_EDGE, aMapVToEdges ); TopTools_ListIteratorOfListOfShape anIt( aVertexList ); for ( ; anIt.More(); anIt.Next() ) { TopoDS_Vertex aV = TopoDS::Vertex( anIt.Value() ); if ( aV.IsNull() || !aMapVToEdges.Contains( aV ) ) continue; const TopTools_ListOfShape& aVertexEdges = aMapVToEdges.FindFromKey( aV ); if ( aVertexEdges.Extent() != 2 ) continue; // no input data to make fillet TopoDS_Edge anEdge1 = TopoDS::Edge( aVertexEdges.First() ); TopoDS_Edge anEdge2 = TopoDS::Edge( aVertexEdges.Last() ); // check if initial edges already modified in previous fillet operation if ( anEdgeToEdgeMap.IsBound( anEdge1 ) ) anEdge1 = TopoDS::Edge(anEdgeToEdgeMap.Find( anEdge1 )); if ( anEdgeToEdgeMap.IsBound( anEdge2 ) ) anEdge2 = TopoDS::Edge(anEdgeToEdgeMap.Find( anEdge2 )); if ( anEdge1.IsNull() || anEdge2.IsNull() || anEdge1.IsSame( anEdge2 ) ) continue; //no input data to make fillet // create plane on 2 edges gp_Pln aPlane; if ( !takePlane(anEdge1, anEdge2, aV, aPlane) ) continue; // seems edges does not belong to same plane or parallel (fillet can not be build) GEOMImpl_Fillet1d aFilletAlgo(anEdge1, anEdge2, aPlane); if ( !aFilletAlgo.Perform(rad) ) continue; // can not create fillet with given radius // take fillet result in given vertex TopoDS_Edge aModifE1, aModifE2; TopoDS_Edge aNewE = aFilletAlgo.Result(BRep_Tool::Pnt(aV), aModifE1, aModifE2); if (aNewE.IsNull()) continue; // no result found // add new created edges and take modified edges aListOfNewEdge.Append( aNewE ); // check if face edges modified, // if yes, than map to original edges (from vertex-edges list), because edges can be modified before if (aModifE1.IsNull() || !anEdge1.IsSame( aModifE1 )) addEdgeRelation( anEdgeToEdgeMap, TopoDS::Edge(aVertexEdges.First()), aModifE1 ); if (aModifE2.IsNull() || !anEdge2.IsSame( aModifE2 )) addEdgeRelation( anEdgeToEdgeMap, TopoDS::Edge(aVertexEdges.Last()), aModifE2 ); } if ( anEdgeToEdgeMap.IsEmpty() && aListOfNewEdge.IsEmpty() ) { StdFail_NotDone::Raise("1D Fillet can't be computed on the given shape with the given radius"); return 0; } // create new wire instead of original for ( TopExp_Explorer anExp( aWire, TopAbs_EDGE ); anExp.More(); anExp.Next() ) { TopoDS_Shape anEdge = anExp.Current(); if ( !anEdgeToEdgeMap.IsBound( anEdge ) ) aListOfNewEdge.Append( anEdge ); else if (!anEdgeToEdgeMap.Find( anEdge ).IsNull()) aListOfNewEdge.Append( anEdgeToEdgeMap.Find( anEdge ) ); } GEOMImpl_IShapesOperations::SortShapes( aListOfNewEdge ); BRepBuilderAPI_MakeWire aWireTool; aWireTool.Add( aListOfNewEdge ); aWireTool.Build(); if (!aWireTool.IsDone()) return 0; aWire = aWireTool.Wire(); aFunction->SetValue(aWire); log.SetTouched(Label()); return 1; }
TopoDS_Shape BlockFix_UnionEdges::Perform(const TopoDS_Shape& Shape, const Standard_Real Tol) { myContext = new ShapeBuild_ReShape; myTolerance = Tol; TopoDS_Shape aResult = myContext->Apply(Shape); // processing each solid TopAbs_ShapeEnum aType = TopAbs_SOLID; TopExp_Explorer exps (Shape, aType); if (!exps.More()) { aType = TopAbs_SHELL; exps.Init(Shape, aType); } for (; exps.More(); exps.Next()) { //TopoDS_Solid aSolid = TopoDS::Solid(exps.Current()); TopoDS_Shape aSolid = exps.Current(); TopTools_IndexedMapOfShape ChangedFaces; // creating map of edge faces TopTools_IndexedDataMapOfShapeListOfShape aMapEdgeFaces; TopExp::MapShapesAndAncestors(aSolid, TopAbs_EDGE, TopAbs_FACE, aMapEdgeFaces); Handle(ShapeBuild_ReShape) aContext = new ShapeBuild_ReShape; TopoDS_Shape aRes = aSolid; aRes = aContext->Apply(aSolid); // processing each face TopExp_Explorer exp; for (exp.Init(aRes, TopAbs_FACE); exp.More(); exp.Next()) { TopoDS_Face aFace = TopoDS::Face(aContext->Apply(exp.Current().Oriented(TopAbs_FORWARD))); TopTools_IndexedDataMapOfShapeListOfShape aMapFacesEdges; for (TopExp_Explorer expe(aFace,TopAbs_EDGE); expe.More(); expe.Next()) { TopoDS_Edge edge = TopoDS::Edge(expe.Current()); if (!aMapEdgeFaces.Contains(edge)) continue; const TopTools_ListOfShape& aList = aMapEdgeFaces.FindFromKey(edge); TopTools_ListIteratorOfListOfShape anIter(aList); for ( ; anIter.More(); anIter.Next()) { TopoDS_Face face = TopoDS::Face(anIter.Value()); TopoDS_Face face1 = TopoDS::Face(aContext->Apply(anIter.Value())); if (face1.IsSame(aFace)) continue; if (aMapFacesEdges.Contains(face)) { aMapFacesEdges.ChangeFromKey(face).Append(edge); } else { TopTools_ListOfShape ListEdges; ListEdges.Append(edge); aMapFacesEdges.Add(face,ListEdges); } } } for (Standard_Integer i=1; i<=aMapFacesEdges.Extent(); i++) { const TopTools_ListOfShape& ListEdges = aMapFacesEdges.FindFromIndex(i); TopTools_SequenceOfShape SeqEdges; TopTools_ListIteratorOfListOfShape anIter(ListEdges); for ( ; anIter.More(); anIter.Next()) { SeqEdges.Append(anIter.Value()); } if (SeqEdges.Length()==1) continue; TopoDS_Edge E; if ( MergeEdges(SeqEdges,aFace,Tol,E) ) { // now we have only one edge - aChain.Value(1) // we have to replace old ListEdges with this new edge aContext->Replace(SeqEdges(1),E); for (Standard_Integer j=2; j<=SeqEdges.Length(); j++) { aContext->Remove(SeqEdges(j)); } TopoDS_Face tmpF = TopoDS::Face(exp.Current()); if ( !ChangedFaces.Contains(tmpF) ) ChangedFaces.Add(tmpF); tmpF = TopoDS::Face(aMapFacesEdges.FindKey(i)); if ( !ChangedFaces.Contains(tmpF) ) ChangedFaces.Add(tmpF); } } } // end processing each face // fix changed faces and replace them in the local context for (Standard_Integer i=1; i<=ChangedFaces.Extent(); i++) { TopoDS_Face aFace = TopoDS::Face(aContext->Apply(ChangedFaces.FindKey(i))); Handle(ShapeFix_Face) sff = new ShapeFix_Face(aFace); sff->SetContext(myContext); sff->SetPrecision(myTolerance); sff->SetMinTolerance(myTolerance); sff->SetMaxTolerance(Max(1.,myTolerance*1000.)); sff->Perform(); aContext->Replace(aFace,sff->Face()); } if (ChangedFaces.Extent() > 0) { // fix changed shell and replace it in the local context TopoDS_Shape aRes1 = aContext->Apply(aRes); TopExp_Explorer expsh; for (expsh.Init(aRes1, TopAbs_SHELL); expsh.More(); expsh.Next()) { TopoDS_Shell aShell = TopoDS::Shell(expsh.Current()); Handle(ShapeFix_Shell) sfsh = new ShapeFix_Shell; sfsh->FixFaceOrientation(aShell); aContext->Replace(aShell,sfsh->Shell()); } TopoDS_Shape aRes2 = aContext->Apply(aRes1); // put new solid into global context myContext->Replace(aSolid,aRes2); } } // end processing each solid aResult = myContext->Apply(Shape); return aResult; }
void CmdPartDesignChamfer::activated(int iMsg) { std::vector<Gui::SelectionObject> selection = getSelection().getSelectionEx(); if (selection.size() != 1) { QMessageBox::warning(Gui::getMainWindow(), QObject::tr("Wrong selection"), QObject::tr("Select an edge, face or body. Only one body is allowed.")); return; } if (!selection[0].isObjectTypeOf(Part::Feature::getClassTypeId())){ QMessageBox::warning(Gui::getMainWindow(), QObject::tr("Wrong object type"), QObject::tr("Chamfer works only on parts")); return; } Part::Feature *base = static_cast<Part::Feature*>(selection[0].getObject()); const Part::TopoShape& TopShape = base->Shape.getShape(); if (TopShape._Shape.IsNull()){ QMessageBox::warning(Gui::getMainWindow(), QObject::tr("Wrong selection"), QObject::tr("Shape of selected part is empty")); return; } TopTools_IndexedMapOfShape mapOfEdges; TopTools_IndexedDataMapOfShapeListOfShape mapEdgeFace; TopExp::MapShapesAndAncestors(TopShape._Shape, TopAbs_EDGE, TopAbs_FACE, mapEdgeFace); TopExp::MapShapes(TopShape._Shape, TopAbs_EDGE, mapOfEdges); std::vector<std::string> SubNames = std::vector<std::string>(selection[0].getSubNames()); int i = 0; while(i < SubNames.size()) { std::string aSubName = static_cast<std::string>(SubNames.at(i)); if (aSubName.size() > 4 && aSubName.substr(0,4) == "Edge") { TopoDS_Edge edge = TopoDS::Edge(TopShape.getSubShape(aSubName.c_str())); const TopTools_ListOfShape& los = mapEdgeFace.FindFromKey(edge); if(los.Extent() != 2) { SubNames.erase(SubNames.begin()+i); continue; } const TopoDS_Shape& face1 = los.First(); const TopoDS_Shape& face2 = los.Last(); GeomAbs_Shape cont = BRep_Tool::Continuity(TopoDS::Edge(edge), TopoDS::Face(face1), TopoDS::Face(face2)); if (cont != GeomAbs_C0) { SubNames.erase(SubNames.begin()+i); continue; } i++; } else if(aSubName.size() > 4 && aSubName.substr(0,4) == "Face") { TopoDS_Face face = TopoDS::Face(TopShape.getSubShape(aSubName.c_str())); TopTools_IndexedMapOfShape mapOfFaces; TopExp::MapShapes(face, TopAbs_EDGE, mapOfFaces); for(int j = 1; j <= mapOfFaces.Extent(); ++j) { TopoDS_Edge edge = TopoDS::Edge(mapOfFaces.FindKey(j)); int id = mapOfEdges.FindIndex(edge); std::stringstream buf; buf << "Edge"; buf << id; if(std::find(SubNames.begin(),SubNames.end(),buf.str()) == SubNames.end()) { SubNames.push_back(buf.str()); } } SubNames.erase(SubNames.begin()+i); } // empty name or any other sub-element else { SubNames.erase(SubNames.begin()+i); } } if (SubNames.size() == 0) { QMessageBox::warning(Gui::getMainWindow(), QObject::tr("Wrong selection"), QObject::tr("No chamfer possible on selected faces/edges")); return; } std::string SelString; SelString += "(App."; SelString += "ActiveDocument";//getObject()->getDocument()->getName(); SelString += "."; SelString += selection[0].getFeatName(); SelString += ",["; for(std::vector<std::string>::const_iterator it = SubNames.begin();it!=SubNames.end();++it){ SelString += "\""; SelString += *it; SelString += "\""; if(it != --SubNames.end()) SelString += ","; } SelString += "])"; std::string FeatName = getUniqueObjectName("Chamfer"); openCommand("Make Chamfer"); doCommand(Doc,"App.activeDocument().addObject(\"PartDesign::Chamfer\",\"%s\")",FeatName.c_str()); doCommand(Doc,"App.activeDocument().%s.Base = %s",FeatName.c_str(),SelString.c_str()); doCommand(Gui,"Gui.activeDocument().hide(\"%s\")",selection[0].getFeatName()); doCommand(Gui,"Gui.activeDocument().setEdit('%s')",FeatName.c_str()); copyVisual(FeatName.c_str(), "ShapeColor", selection[0].getFeatName()); copyVisual(FeatName.c_str(), "LineColor", selection[0].getFeatName()); copyVisual(FeatName.c_str(), "PointColor", selection[0].getFeatName()); }