//======================================================================= // function: FillImagesEdges // purpose: //======================================================================= void GEOMAlgo_Builder::FillImagesEdges() { myErrorStatus=0; // const NMTDS_ShapesDataStructure& aDS=*myPaveFiller->DS(); NMTTools_PaveFiller* pPF=myPaveFiller; const BOPTools_SplitShapesPool& aSSP=pPF->SplitShapesPool(); const Handle(IntTools_Context)& aCtx=pPF->Context(); // Standard_Boolean bToReverse; Standard_Integer i, aNb, aNbSp, nSp, nSpR, nSpx, aIsCB, aNbLB; TColStd_ListIteratorOfListOfInteger aItLB; TColStd_ListOfInteger aLB; TopoDS_Edge aEE, aESpR; TopTools_MapOfShape aMFence; TopTools_ListOfShape aLSp; TopTools_ListIteratorOfListOfShape aIt1; BOPTools_ListIteratorOfListOfPaveBlock aIt; // aNb=aDS.NumberOfShapesOfTheObject(); for (i=1; i<=aNb; ++i) { const TopoDS_Shape& aE=aDS.Shape(i); if (aE.ShapeType()!=TopAbs_EDGE) { continue; } // if (!aMFence.Add(aE)) { continue; } // const BOPTools_ListOfPaveBlock& aLPB=aSSP(aDS.RefEdge(i)); aNbSp=aLPB.Extent(); if (!aNbSp) { continue; } // aEE=TopoDS::Edge(aE); aLSp.Clear(); // if (aNbSp==1) { const BOPTools_PaveBlock& aPB=aLPB.First(); nSp=aPB.Edge(); const TopoDS_Shape& aSp=aDS.Shape(nSp); // const BOPTools_PaveBlock& aPBR=pPF->RealPaveBlock(aPB, aLB, aIsCB); //modified by NIZNHY-PKV Wed Oct 27 11:19:30 2010f aNbLB=aLB.Extent(); if (aIsCB && aNbLB<2) { aIsCB=0; } //modified by NIZNHY-PKV Wed Oct 27 11:19:34 2010t // nSpR=aPBR.Edge(); const TopoDS_Shape& aSpR=aDS.Shape(nSpR); if (aSpR.IsSame(aSp) && aSpR.IsSame(aE) && !aIsCB) { continue; } // aESpR=TopoDS::Edge(aSpR); bToReverse=GEOMAlgo_Tools3D::IsSplitToReverse(aESpR, aEE, aCtx); if (bToReverse) { aESpR.Reverse(); } aLSp.Append(aESpR); // aItLB.Initialize(aLB); for (; aItLB.More(); aItLB.Next()) { nSpx=aItLB.Value(); const TopoDS_Shape& aSpx=aDS.Shape(nSpx); mySameDomainShapes.Add(aSpx ,aSpR); } // // }// if (aNbSp==1) { else { aIt.Initialize(aLPB); for (; aIt.More(); aIt.Next()) { const BOPTools_PaveBlock& aPB=aIt.Value(); const BOPTools_PaveBlock& aPBR=pPF->RealPaveBlock(aPB, aLB, aIsCB); nSpR=aPBR.Edge(); const TopoDS_Shape& aSpR=aDS.Shape(nSpR); // aESpR=TopoDS::Edge(aSpR); bToReverse=GEOMAlgo_Tools3D::IsSplitToReverse(aESpR, aEE, aCtx); if (bToReverse) { aESpR.Reverse(); } aLSp.Append(aESpR); // aItLB.Initialize(aLB); for (; aItLB.More(); aItLB.Next()) { nSpx=aItLB.Value(); const TopoDS_Shape& aSpx=aDS.Shape(nSpx); mySameDomainShapes.Add(aSpx ,aSpR); } } } // myImages.Bind(aE, aLSp); }//for (i=1; i<=aNb; ++i) }
//======================================================================= //function : GetEdgeNearPoint //purpose : //======================================================================= TopoDS_Shape GEOMUtils::GetEdgeNearPoint (const TopoDS_Shape& theShape, const TopoDS_Vertex& thePoint) { TopoDS_Shape aResult; // 1. Explode the shape on edges TopTools_MapOfShape mapShape; Standard_Integer nbEdges = 0; TopExp_Explorer exp (theShape, TopAbs_EDGE); for (; exp.More(); exp.Next()) { if (mapShape.Add(exp.Current())) { nbEdges++; } } if (nbEdges == 0) Standard_NullObject::Raise("Given shape contains no edges"); mapShape.Clear(); Standard_Integer ind = 1; TopTools_Array1OfShape anEdges (1, nbEdges); TColStd_Array1OfReal aDistances (1, nbEdges); for (exp.Init(theShape, TopAbs_EDGE); exp.More(); exp.Next()) { if (mapShape.Add(exp.Current())) { TopoDS_Shape anEdge = exp.Current(); anEdges(ind) = anEdge; // 2. Classify the point relatively each edge BRepExtrema_DistShapeShape aDistTool (thePoint, anEdges(ind)); if (!aDistTool.IsDone()) Standard_ConstructionError::Raise("Cannot find a distance from the given point to one of edges"); aDistances(ind) = aDistTool.Value(); ind++; } } // 3. Define edge, having minimum distance to the point Standard_Real nearest = RealLast(), nbFound = 0; Standard_Real prec = Precision::Confusion(); for (ind = 1; ind <= nbEdges; ind++) { if (Abs(aDistances(ind) - nearest) < prec) { nbFound++; } else if (aDistances(ind) < nearest) { nearest = aDistances(ind); aResult = anEdges(ind); nbFound = 1; } else { } } if (nbFound > 1) { Standard_ConstructionError::Raise("Multiple edges near the given point are found"); } else if (nbFound == 0) { Standard_ConstructionError::Raise("There are no edges near the given point"); } else { } return aResult; }
//======================================================================= //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 : 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 : BuildSplitSolids //purpose : //======================================================================= void GEOMAlgo_Builder::BuildSplitSolids() { myErrorStatus=0; // const NMTDS_ShapesDataStructure& aDS=*myPaveFiller->DS(); NMTTools_PaveFiller* pPF=myPaveFiller; const Handle(IntTools_Context)& aCtx= pPF->Context(); // Standard_Integer i, aNbS, iErr; TopExp_Explorer aExp; TopTools_ListOfShape aSFS, aLSEmpty; TopTools_MapOfShape aMFence; TopTools_ListIteratorOfListOfShape aIt; GEOMAlgo_BuilderSolid aSB; GEOMAlgo_DataMapIteratorOfDataMapOfShapeShapeSet aItSS; GEOMAlgo_DataMapOfShapeShapeSet aMSS; GEOMAlgo_ShapeSet aSSi; // // 0. Find same domain solids for non-interferred solids aNbS=aDS.NumberOfShapesOfTheObject(); for (i=1; i<=aNbS; ++i) { const TopoDS_Shape& aS=aDS.Shape(i); if (aS.ShapeType()!=TopAbs_SOLID) { continue; } if (!aMFence.Add(aS)) { continue; } if(myDraftSolids.Contains(aS)) { continue; } // aSSi.Clear(); aSSi.Add(aS, TopAbs_FACE); // aMSS.Bind(aS, aSSi); } //for (i=1; i<=aNbS; ++i) // // 1. Build solids for interferred source solids aSB.SetContext(aCtx); aSB.ComputeInternalShapes(myComputeInternalShapes); aNbS=myDraftSolids.Extent(); for (i=1; i<=aNbS; ++i) { const TopoDS_Shape& aS =myDraftSolids.FindKey(i); const TopoDS_Shape& aSD=myDraftSolids.FindFromIndex(i); const TopTools_ListOfShape& aLFIN= (myInParts.Contains(aS)) ? myInParts.FindFromKey(aS) : aLSEmpty; // // 1.1 Fill Shell Faces Set aSFS.Clear(); aExp.Init(aSD, TopAbs_FACE); for (; aExp.More(); aExp.Next()) { const TopoDS_Shape& aF=aExp.Current(); aSFS.Append(aF); } // aIt.Initialize(aLFIN); for (; aIt.More(); aIt.Next()) { TopoDS_Shape aF=aIt.Value(); // aF.Orientation(TopAbs_FORWARD); aSFS.Append(aF); aF.Orientation(TopAbs_REVERSED); aSFS.Append(aF); } // Standard_Integer aNbSFS; aNbSFS=aSFS.Extent(); // // 1.2 // Check whether aSFS contains a subsets of faces // of solids that have been already built. // If yes, shrink aSFS by these subsets. aSSi.Clear(); aSSi.Add(aSFS); // aItSS.Initialize(aMSS); for (; aItSS.More(); aItSS.Next()) { const TopoDS_Shape& aSR=aItSS.Key(); const GEOMAlgo_ShapeSet& aSSR=aItSS.Value(); if (aSSi.Contains(aSSR)) { // the aSR is SD solid for aS aSSi.Subtract(aSSR); // update images if(myImages.HasImage(aS)) { myImages.Add(aS, aSR); } else { myImages.Bind(aS, aSR); } // // update SD Shapes mySameDomainShapes.Add(aSR, aSR); } } const TopTools_ListOfShape& aSFS1=aSSi.GetSet(); aNbSFS=aSFS1.Extent(); //modified by NIZNHY-PKV Wed Oct 27 09:53:15 2010f if (!aNbSFS) { continue; } //modified by NIZNHY-PKV Wed Oct 27 09:53:18 2010t // // 1.3 Build new solids aSB.SetContext(aCtx); aSB.SetShapes(aSFS1); aSB.Perform(); iErr=aSB.ErrorStatus(); if (iErr) { myErrorStatus=30; // SolidBuilder failed return; } // const TopTools_ListOfShape& aLSR=aSB.Areas(); // // 1.4 Collect resulting solids and theirs set of faces aIt.Initialize(aLSR); for (; aIt.More(); aIt.Next()) { const TopoDS_Shape& aSR=aIt.Value(); // aSSi.Clear(); aExp.Init(aSR, TopAbs_FACE); for (; aExp.More(); aExp.Next()) { const TopoDS_Shape& aF=aExp.Current(); aSSi.Add(aF); } aMSS.Bind(aSR, aSSi); } // // Update images if (myImages.HasImage(aS)) { myImages.Add(aS, aLSR); } else { myImages.Bind(aS, aLSR); } } // for (i=1; i<=aNbS; ++i) { }
//======================================================================= //function : DetectVertices //purpose : //======================================================================= void GEOMAlgo_GlueDetector::DetectVertices() { Standard_Integer j, i, aNbV, aNbVSD; Standard_Real aTolV; gp_Pnt aPV; TColStd_ListIteratorOfListOfInteger aIt; TopoDS_Shape aVF; TopTools_IndexedMapOfShape aMV; TopTools_MapOfShape aMVProcessed; TopTools_ListIteratorOfListOfShape aItS; TopTools_DataMapIteratorOfDataMapOfShapeListOfShape aItIm; TopTools_DataMapOfShapeListOfShape aMVV; GEOMAlgo_IndexedDataMapOfIntegerShape aMIS; NMTDS_IndexedDataMapOfShapeBndSphere aMSB; // NMTDS_BndSphereTreeSelector aSelector; NMTDS_BndSphereTree aBBTree; NCollection_UBTreeFiller <Standard_Integer, NMTDS_BndSphere> aTreeFiller(aBBTree); // myErrorStatus=0; // TopExp::MapShapes(myArgument, TopAbs_VERTEX, aMV); aNbV=aMV.Extent(); if (!aNbV) { myErrorStatus=2; // no vertices in source shape return; } // for (i=1; i<=aNbV; ++i) { NMTDS_BndSphere aBox; // const TopoDS_Vertex& aV=*((TopoDS_Vertex*)&aMV(i)); aPV=BRep_Tool::Pnt(aV); aTolV=BRep_Tool::Tolerance(aV); // aBox.SetGap(myTolerance); aBox.SetCenter(aPV); aBox.SetRadius(aTolV); // aTreeFiller.Add(i, aBox); // aMIS.Add(i, aV); aMSB.Add(aV, aBox); } // aTreeFiller.Fill(); // //--------------------------------------------------- // Chains for (i=1; i<=aNbV; ++i) { const TopoDS_Shape& aV=aMV(i); // if (aMVProcessed.Contains(aV)) { continue; } // Standard_Integer aNbIP, aIP, aNbIP1, aIP1; TopTools_ListOfShape aLVSD; TColStd_MapOfInteger aMIP, aMIP1, aMIPC; TColStd_MapIteratorOfMapOfInteger aIt1; // aMIP.Add(i); while(1) { aNbIP=aMIP.Extent(); aIt1.Initialize(aMIP); for(; aIt1.More(); aIt1.Next()) { aIP=aIt1.Key(); if (aMIPC.Contains(aIP)) { continue; } // const TopoDS_Shape& aVP=aMIS.FindFromKey(aIP); const NMTDS_BndSphere& aBoxVP=aMSB.FindFromKey(aVP); // aSelector.Clear(); aSelector.SetBox(aBoxVP); // aNbVSD=aBBTree.Select(aSelector); if (!aNbVSD) { continue; // it shoild not be so [at least IP itself] } // const TColStd_ListOfInteger& aLI=aSelector.Indices(); aIt.Initialize(aLI); for (; aIt.More(); aIt.Next()) { aIP1=aIt.Value(); if (aMIP.Contains(aIP1)) { continue; } aMIP1.Add(aIP1); } //for (; aIt.More(); aIt.Next()) { }//for(; aIt1.More(); aIt1.Next()) { // aNbIP1=aMIP1.Extent(); if (!aNbIP1) { break; } // aIt1.Initialize(aMIP); for(; aIt1.More(); aIt1.Next()) { aIP=aIt1.Key(); aMIPC.Add(aIP); } // aMIP.Clear(); aIt1.Initialize(aMIP1); for(; aIt1.More(); aIt1.Next()) { aIP=aIt1.Key(); aMIP.Add(aIP); } aMIP1.Clear(); }// while(1) // // Fill myImages aNbIP=aMIPC.Extent(); // if (!aNbIP) {// no SD vertices is found aMVProcessed.Add(aV); continue; } //else { // SD vertices founded [ aMIPC ] aIt1.Initialize(aMIPC); for(j=0; aIt1.More(); aIt1.Next(), ++j) { aIP=aIt1.Key(); const TopoDS_Shape& aVP=aMIS.FindFromKey(aIP); if (!j) { aVF=aVP; } aLVSD.Append(aVP); aMVProcessed.Add(aVP); } //} myImages.Bind(aVF, aLVSD); }// for (i=1; i<=aNbV; ++i) { //------------------------------ // Origins aItIm.Initialize(myImages); for (; aItIm.More(); aItIm.Next()) { const TopoDS_Shape& aV=aItIm.Key(); const TopTools_ListOfShape& aLVSD=aItIm.Value(); aItS.Initialize(aLVSD); for (; aItS.More(); aItS.Next()) { const TopoDS_Shape& aVSD=aItS.Value(); if (!myOrigins.IsBound(aVSD)) { myOrigins.Bind(aVSD, aV); } } } }
bool StdMeshers_RadialPrism_3D::Evaluate(SMESH_Mesh& aMesh, const TopoDS_Shape& aShape, MapShapeNbElems& aResMap) { // get 2 shells TopoDS_Solid solid = TopoDS::Solid( aShape ); TopoDS_Shell outerShell = BRepClass3d::OuterShell( solid ); TopoDS_Shape innerShell; int nbShells = 0; for ( TopoDS_Iterator It (solid); It.More(); It.Next(), ++nbShells ) if ( !outerShell.IsSame( It.Value() )) innerShell = It.Value(); if ( nbShells != 2 ) { std::vector<int> aResVec(SMDSEntity_Last); for(int i=SMDSEntity_Node; i<SMDSEntity_Last; i++) aResVec[i] = 0; SMESH_subMesh * sm = aMesh.GetSubMesh(aShape); aResMap.insert(std::make_pair(sm,aResVec)); SMESH_ComputeErrorPtr& smError = sm->GetComputeError(); smError.reset( new SMESH_ComputeError(COMPERR_ALGO_FAILED,"Submesh can not be evaluated",this)); return false; } // Associate sub-shapes of the shells ProjectionUtils::TShapeShapeMap shape2ShapeMap; if ( !ProjectionUtils::FindSubShapeAssociation( outerShell, &aMesh, innerShell, &aMesh, shape2ShapeMap) ) { std::vector<int> aResVec(SMDSEntity_Last); for(int i=SMDSEntity_Node; i<SMDSEntity_Last; i++) aResVec[i] = 0; SMESH_subMesh * sm = aMesh.GetSubMesh(aShape); aResMap.insert(std::make_pair(sm,aResVec)); SMESH_ComputeErrorPtr& smError = sm->GetComputeError(); smError.reset( new SMESH_ComputeError(COMPERR_ALGO_FAILED,"Submesh can not be evaluated",this)); return false; } // get info for outer shell int nb0d_Out=0, nb2d_3_Out=0, nb2d_4_Out=0; //TopTools_SequenceOfShape FacesOut; for (TopExp_Explorer exp(outerShell, TopAbs_FACE); exp.More(); exp.Next()) { //FacesOut.Append(exp.Current()); SMESH_subMesh *aSubMesh = aMesh.GetSubMesh(exp.Current()); MapShapeNbElemsItr anIt = aResMap.find(aSubMesh); std::vector<int> aVec = (*anIt).second; nb0d_Out += aVec[SMDSEntity_Node]; nb2d_3_Out += Max(aVec[SMDSEntity_Triangle],aVec[SMDSEntity_Quad_Triangle]); nb2d_4_Out += Max(aVec[SMDSEntity_Quadrangle],aVec[SMDSEntity_Quad_Quadrangle]); } int nb1d_Out = 0; TopTools_MapOfShape tmpMap; for (TopExp_Explorer exp(outerShell, TopAbs_EDGE); exp.More(); exp.Next()) { if( tmpMap.Contains( exp.Current() ) ) continue; tmpMap.Add( exp.Current() ); SMESH_subMesh *aSubMesh = aMesh.GetSubMesh(exp.Current()); MapShapeNbElemsItr anIt = aResMap.find(aSubMesh); std::vector<int> aVec = (*anIt).second; nb0d_Out += aVec[SMDSEntity_Node]; nb1d_Out += Max(aVec[SMDSEntity_Edge],aVec[SMDSEntity_Quad_Edge]); } tmpMap.Clear(); for (TopExp_Explorer exp(outerShell, TopAbs_VERTEX); exp.More(); exp.Next()) { if( tmpMap.Contains( exp.Current() ) ) continue; tmpMap.Add( exp.Current() ); nb0d_Out++; } // get info for inner shell int nb0d_In=0, nb2d_3_In=0, nb2d_4_In=0; //TopTools_SequenceOfShape FacesIn; for (TopExp_Explorer exp(innerShell, TopAbs_FACE); exp.More(); exp.Next()) { //FacesIn.Append(exp.Current()); SMESH_subMesh *aSubMesh = aMesh.GetSubMesh(exp.Current()); MapShapeNbElemsItr anIt = aResMap.find(aSubMesh); std::vector<int> aVec = (*anIt).second; nb0d_In += aVec[SMDSEntity_Node]; nb2d_3_In += Max(aVec[SMDSEntity_Triangle],aVec[SMDSEntity_Quad_Triangle]); nb2d_4_In += Max(aVec[SMDSEntity_Quadrangle],aVec[SMDSEntity_Quad_Quadrangle]); } int nb1d_In = 0; tmpMap.Clear(); bool IsQuadratic = false; bool IsFirst = true; for (TopExp_Explorer exp(innerShell, TopAbs_EDGE); exp.More(); exp.Next()) { if( tmpMap.Contains( exp.Current() ) ) continue; tmpMap.Add( exp.Current() ); SMESH_subMesh *aSubMesh = aMesh.GetSubMesh(exp.Current()); MapShapeNbElemsItr anIt = aResMap.find(aSubMesh); std::vector<int> aVec = (*anIt).second; nb0d_In += aVec[SMDSEntity_Node]; nb1d_In += Max(aVec[SMDSEntity_Edge],aVec[SMDSEntity_Quad_Edge]); if(IsFirst) { IsQuadratic = (aVec[SMDSEntity_Quad_Edge] > aVec[SMDSEntity_Edge]); IsFirst = false; } } tmpMap.Clear(); for (TopExp_Explorer exp(innerShell, TopAbs_VERTEX); exp.More(); exp.Next()) { if( tmpMap.Contains( exp.Current() ) ) continue; tmpMap.Add( exp.Current() ); nb0d_In++; } bool IsOK = (nb0d_Out==nb0d_In) && (nb1d_Out==nb1d_In) && (nb2d_3_Out==nb2d_3_In) && (nb2d_4_Out==nb2d_4_In); if(!IsOK) { std::vector<int> aResVec(SMDSEntity_Last); for(int i=SMDSEntity_Node; i<SMDSEntity_Last; i++) aResVec[i] = 0; SMESH_subMesh * sm = aMesh.GetSubMesh(aShape); aResMap.insert(std::make_pair(sm,aResVec)); SMESH_ComputeErrorPtr& smError = sm->GetComputeError(); smError.reset( new SMESH_ComputeError(COMPERR_ALGO_FAILED,"Submesh can not be evaluated",this)); return false; } int nbLayers = 0; if( myNbLayerHypo ) { nbLayers = myNbLayerHypo->GetNumberOfLayers(); } if ( myDistributionHypo ) { if ( !myDistributionHypo->GetLayerDistribution() ) { std::vector<int> aResVec(SMDSEntity_Last); for(int i=SMDSEntity_Node; i<SMDSEntity_Last; i++) aResVec[i] = 0; SMESH_subMesh * sm = aMesh.GetSubMesh(aShape); aResMap.insert(std::make_pair(sm,aResVec)); SMESH_ComputeErrorPtr& smError = sm->GetComputeError(); smError.reset( new SMESH_ComputeError(COMPERR_ALGO_FAILED,"Submesh can not be evaluated",this)); return false; } TopExp_Explorer exp(outerShell, TopAbs_VERTEX); TopoDS_Vertex Vout = TopoDS::Vertex(exp.Current()); TopoDS_Vertex Vin = TopoDS::Vertex( shape2ShapeMap(Vout) ); if ( myLayerPositions.empty() ) { gp_Pnt pIn = BRep_Tool::Pnt(Vin); gp_Pnt pOut = BRep_Tool::Pnt(Vout); computeLayerPositions( pIn, pOut ); } nbLayers = myLayerPositions.size() + 1; } std::vector<int> aResVec(SMDSEntity_Last); for(int i=SMDSEntity_Node; i<SMDSEntity_Last; i++) aResVec[i] = 0; if(IsQuadratic) { aResVec[SMDSEntity_Quad_Penta] = nb2d_3_Out * nbLayers; aResVec[SMDSEntity_Quad_Hexa] = nb2d_4_Out * nbLayers; int nb1d = ( nb2d_3_Out*3 + nb2d_4_Out*4 ) / 2; aResVec[SMDSEntity_Node] = nb0d_Out * ( 2*nbLayers - 1 ) - nb1d * nbLayers; } else { aResVec[SMDSEntity_Node] = nb0d_Out * ( nbLayers - 1 ); aResVec[SMDSEntity_Penta] = nb2d_3_Out * nbLayers; aResVec[SMDSEntity_Hexa] = nb2d_4_Out * nbLayers; } SMESH_subMesh * sm = aMesh.GetSubMesh(aShape); aResMap.insert(std::make_pair(sm,aResVec)); return true; }
//======================================================================= // function: BuildSplitFaces // purpose: //======================================================================= void GEOMAlgo_Builder::BuildSplitFaces() { const NMTDS_ShapesDataStructure& aDS=*myPaveFiller->DS(); NMTTools_PaveFiller* pPF=myPaveFiller; NMTDS_InterfPool* pIP=pPF->IP(); BOPTools_CArray1OfSSInterference& aFFs=pIP->SSInterferences(); IntTools_Context& aCtx= pPF->ChangeContext(); // Standard_Boolean bToReverse, bIsClosed, bIsDegenerated; Standard_Integer i, aNb, aNbF, nF; TopTools_MapOfShape aMFence; TColStd_IndexedMapOfInteger aMFP; TopExp_Explorer anExp; TopoDS_Face aFF; TopoDS_Edge aSp, aEE; TopTools_ListIteratorOfListOfShape aIt; TopAbs_Orientation anOriF, anOriE; // mySplitFaces.Clear(); // // 1. Select Faces to process (MFP) aNb=aDS.NumberOfShapesOfTheObject(); for (i=1; i<=aNb; ++i) { const TopoDS_Shape& aF=aDS.Shape(i); if (aF.ShapeType()!=TopAbs_FACE) { continue; } if (!aMFence.Add(aF)) { continue; } // if (myInParts.Contains(aF)) { aMFP.Add(i); continue; } // anExp.Init(aF, TopAbs_EDGE); for (; anExp.More(); anExp.Next()) { const TopoDS_Shape& aE=anExp.Current(); if (myImages.HasImage(aE)) { aMFP.Add(i); break; } } // //=== { Standard_Integer aNbFFs, aNbSE, j, n1, n2; // aNbFFs=aFFs.Extent(); for (j=1; j<=aNbFFs; ++j) { BOPTools_SSInterference& aFFj=aFFs(j); aFFj.Indices(n1, n2); if (!(n1==i || n2==i)) { continue; } // const TColStd_ListOfInteger& aLSE=aFFj.SharedEdges(); aNbSE=aLSE.Extent(); if (aNbSE) { aMFP.Add(i); break; } } } //=== // }// for (i=1; i<=aNb; ++i) // // 2. ProcessFaces aNbF=aMFP.Extent(); for (i=1; i<=aNbF; ++i) { nF=aMFP(i); const TopoDS_Face& aF=TopoDS::Face(aDS.Shape(nF)); anOriF=aF.Orientation(); aFF=aF; aFF.Orientation(TopAbs_FORWARD); // aMFence.Clear(); // // 2.1. Fill WES GEOMAlgo_WireEdgeSet aWES; aWES.SetFace(aFF); // // 2.1.1. Add Split parts anExp.Init(aFF, TopAbs_EDGE); for (; anExp.More(); anExp.Next()) { const TopoDS_Edge& aE=TopoDS::Edge(anExp.Current()); anOriE=aE.Orientation(); // if (!myImages.HasImage(aE)) { if (anOriE==TopAbs_INTERNAL) { aEE=aE; aEE.Orientation(TopAbs_FORWARD); aWES.AddStartElement(aEE); aEE.Orientation(TopAbs_REVERSED); aWES.AddStartElement(aEE); } else { aWES.AddStartElement(aE); } continue; } // bIsDegenerated=BRep_Tool::Degenerated(aE); bIsClosed=BRep_Tool::IsClosed(aE, aF); // const TopTools_ListOfShape& aLIE=myImages.Image(aE); aIt.Initialize(aLIE); for (; aIt.More(); aIt.Next()) { aSp=TopoDS::Edge(aIt.Value()); // if (bIsDegenerated) { aSp.Orientation(anOriE); aWES.AddStartElement(aSp); continue; } // if (anOriE==TopAbs_INTERNAL) { aSp.Orientation(TopAbs_FORWARD); aWES.AddStartElement(aSp); aSp.Orientation(TopAbs_REVERSED); aWES.AddStartElement(aSp); continue; } // if (bIsClosed){ if (aMFence.Add(aSp)) { // if (!BRep_Tool::IsClosed(aSp, aF)){ BOPTools_Tools3D::DoSplitSEAMOnFace(aSp, aF); } // aSp.Orientation(TopAbs_FORWARD); aWES.AddStartElement(aSp); aSp.Orientation(TopAbs_REVERSED); aWES.AddStartElement(aSp); } continue; }// if (aMFence.Add(aSp)) // aSp.Orientation(anOriE); bToReverse=BOPTools_Tools3D::IsSplitToReverse1(aSp, aE, aCtx); if (bToReverse) { aSp.Reverse(); } aWES.AddStartElement(aSp); }// for (; aIt.More(); aIt.Next()) { }// for (; anExp.More(); anExp.Next()) { // // 2.1.2. Add In2D Parts if (myInParts.Contains(aF)) { const TopTools_ListOfShape& aLE=myInParts.FindFromKey(aF); aIt.Initialize(aLE); for (; aIt.More(); aIt.Next()) { aSp=TopoDS::Edge(aIt.Value()); // aSp.Orientation(TopAbs_FORWARD); aWES.AddStartElement(aSp); // aSp.Orientation(TopAbs_REVERSED); aWES.AddStartElement(aSp); } } // // 2.2. Build images Faces TopTools_ListOfShape aLFR; GEOMAlgo_ShapeSet aS1, aS2; // const TopTools_ListOfShape& aSE=aWES.StartElements(); aS1.Add(aSE); aS2.Add(aFF, TopAbs_EDGE); if (aS1.IsEqual(aS2)) { aLFR.Append(aF); } else { GEOMAlgo_BuilderFace aBF; // aBF.SetFace(aFF); aBF.SetContext(aCtx); /* { TopoDS_Compound aCx; BRep_Builder aBBx; TopTools_ListIteratorOfListOfShape aItx; // aBBx.MakeCompound(aCx); aBBx.Add(aCx, aFF); aItx.Initialize(aSE); for (; aItx.More(); aItx.Next()) { TopoDS_Shape& aEx=aItx.Value(); aBBx.Add(aCx, aEx); } int a=0; } */ aBF.SetShapes(aSE); // <-DEB aBF.Perform(); // const TopTools_ListOfShape& aLF=aBF.Areas(); aIt.Initialize(aLF); for (; aIt.More(); aIt.Next()) { TopoDS_Shape& aFR=aIt.Value(); if (anOriF==TopAbs_REVERSED) { aFR.Orientation(TopAbs_REVERSED); } aLFR.Append(aFR); } } // // 2.3. Collect draft images Faces mySplitFaces.Bind(aF, aLFR); }//for (i=1; i<=aNbF; ++i) }
//======================================================================= // function: FillSameDomainFaces // purpose: //======================================================================= void GEOMAlgo_Builder::FillSameDomainFaces() { Standard_Boolean bIsSDF, bHasImage1, bHasImage2, bForward; Standard_Integer i, j, aNbFF, nF1, nF2, aNbPBInOn, aNbC, aNbSE; Standard_Integer aNbF1, aNbF2, i2s, aNbSD; TopTools_MapOfShape aMFence; TopTools_ListOfShape aLX1, aLX2; TopTools_ListIteratorOfListOfShape aItF1, aItF2; NMTTools_ListOfCoupleOfShape aLCS; // const NMTDS_ShapesDataStructure& aDS=*myPaveFiller->DS(); NMTTools_PaveFiller* pPF=myPaveFiller; NMTDS_InterfPool* pIP=pPF->IP(); BOPTools_CArray1OfSSInterference& aFFs=pIP->SSInterferences(); IntTools_Context& aCtx= pPF->ChangeContext(); // // //mySameDomainShapes.Clear(); // // 1. For each FF find among images of faces // all pairs of same domain faces (SDF) [=> aLCS] aNbFF=aFFs.Extent(); for (i=1; i<=aNbFF; ++i) { BOPTools_SSInterference& aFF=aFFs(i); aFF.Indices(nF1, nF2); // const TopoDS_Face& aF1=TopoDS::Face(aDS.Shape(nF1)); const TopoDS_Face& aF2=TopoDS::Face(aDS.Shape(nF2)); // // if there are no in/on 2D split parts the faces nF1, nF2 // can not be SDF const BOPTools_ListOfPaveBlock& aLPBInOn=aFF.PaveBlocks(); aNbPBInOn=aLPBInOn.Extent(); // //=== const TColStd_ListOfInteger& aLSE=aFF.SharedEdges(); aNbSE=aLSE.Extent(); if (!aNbPBInOn && !aNbSE) { continue; } //=== // // if there is at least one section edge between faces nF1, nF2 // they can not be SDF BOPTools_SequenceOfCurves& aSC=aFF.Curves(); aNbC=aSC.Length(); if (aNbC) { continue; } // // the faces are suspected to be SDF. // Try to find SDF among images of nF1, nF2 aMFence.Clear(); // //-------------------------------------------------------- bHasImage1=mySplitFaces.HasImage(aF1); bHasImage2=mySplitFaces.HasImage(aF2); // aLX1.Clear(); if (!bHasImage1) { aLX1.Append(aF1); } // aLX2.Clear(); if (!bHasImage2) { aLX2.Append(aF2); } // const TopTools_ListOfShape& aLF1r=(bHasImage1)? mySplitFaces.Image(aF1) : aLX1; const TopTools_ListOfShape& aLF2r=(bHasImage2)? mySplitFaces.Image(aF2) : aLX2; // TopTools_DataMapOfIntegerShape aMIS; TColStd_ListIteratorOfListOfInteger aItLI; NMTDS_BoxBndTreeSelector aSelector; NMTDS_BoxBndTree aBBTree; NCollection_UBTreeFiller <Standard_Integer, Bnd_Box> aTreeFiller(aBBTree); // aNbF1=aLF1r.Extent(); aNbF2=aLF2r.Extent(); bForward=(aNbF1<aNbF2); // const TopTools_ListOfShape& aLF1=bForward ? aLF1r : aLF2r; const TopTools_ListOfShape& aLF2=bForward ? aLF2r : aLF1r; // // 1. aTreeFiller aItF2.Initialize(aLF2); for (i2s=1; aItF2.More(); aItF2.Next(), ++i2s) { Bnd_Box aBoxF2s; // const TopoDS_Face& aF2s=*((TopoDS_Face*)(&aItF2.Value())); // BRepBndLib::Add(aF2s, aBoxF2s); // aMIS.Bind(i2s, aF2s); // aTreeFiller.Add(i2s, aBoxF2s); }//for (i2s=1; aItF2.More(); aItF2.Next(), ++i2s) { // aTreeFiller.Fill(); // // 2. aItF1.Initialize(aLF1); for (j=1; aItF1.More(); aItF1.Next(), ++j) { Bnd_Box aBoxF1x; // const TopoDS_Face& aF1x=*((TopoDS_Face*)(&aItF1.Value())); // BRepBndLib::Add(aF1x, aBoxF1x); // aSelector.Clear(); aSelector.SetBox(aBoxF1x); aNbSD=aBBTree.Select(aSelector); if (!aNbSD) { continue; } // const TColStd_ListOfInteger& aLI=aSelector.Indices(); aItLI.Initialize(aLI); for (; aItLI.More(); aItLI.Next()) { i2s=aItLI.Value(); const TopoDS_Face& aF2y=*((TopoDS_Face*)(&aMIS.Find(i2s))); // bIsSDF=NMTTools_Tools::AreFacesSameDomain(aF1x, aF2y, aCtx); if (bIsSDF) { if (aMFence.Contains(aF1x) || aMFence.Contains(aF2y)) { continue; } aMFence.Add(aF1x); aMFence.Add(aF2y); // NMTTools_CoupleOfShape aCS; // aCS.SetShape1(aF1x); aCS.SetShape2(aF2y); aLCS.Append(aCS); // if (bForward) { if (aF1x==aF1) { if (!mySplitFaces.HasImage(aF1)) { mySplitFaces.Bind(aF1, aF1); } } if (aF2y==aF2) { if (!mySplitFaces.HasImage(aF2)) { mySplitFaces.Bind(aF2, aF2); } } } else { if (aF1x==aF2) { if (!mySplitFaces.HasImage(aF2)) { mySplitFaces.Bind(aF2, aF2); } } if (aF2y==aF1) { if (!mySplitFaces.HasImage(aF1)) { mySplitFaces.Bind(aF1, aF1); } } } // break; }//if (bIsSDF) { }//for (; aItLI.More(); aItLI.Next()) { }//for (; aItF1.More(); aItF1.Next()) { }//for (i=1; i<=aNbFF; ++i) // aNbC=aLCS.Extent(); if (!aNbC) { return; } // // 2. Find Chains NMTTools_IndexedDataMapOfShapeIndexedMapOfShape aMC; // NMTTools_Tools::FindChains(aLCS, aMC); // // 3. Fill the map of SDF mySameDomainFaces aNbC=aMC.Extent(); for (i=1; i<=aNbC; ++i) { const TopoDS_Shape& aF=aMC.FindKey(i); const TopTools_IndexedMapOfShape& aMSDF=aMC(i); // aNbFF=aMSDF.Extent(); for (j=1; j<=aNbFF; ++j) { const TopoDS_Shape& aFSD=aMSDF(j); mySameDomainShapes.Add(aFSD, aF); } } // }
//======================================================================= //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; }
//======================================================================= // function: FillIn2DParts // purpose: //======================================================================= void GEOMAlgo_Builder::FillIn2DParts() { const NMTDS_ShapesDataStructure& aDS=*myPaveFiller->DS(); NMTTools_PaveFiller* pPF=myPaveFiller; NMTDS_InterfPool* pIP=pPF->IP(); BOPTools_CArray1OfSSInterference& aFFs=pIP->SSInterferences(); NMTTools_CommonBlockPool& aCBP=pPF->ChangeCommonBlockPool(); // Standard_Integer j, nSpIn, nSpSc, aNbCurves; Standard_Integer aNbS, nF, aNbCBP, n1, n2, aNbFFs, aNbSpIn; TopTools_MapOfShape aMFence; TopTools_ListOfShape aLSpIn; TopoDS_Face aF; NMTTools_ListIteratorOfListOfCommonBlock aItCB; BOPTools_ListIteratorOfListOfPaveBlock aItPB; // myInParts.Clear(); // aNbFFs=aFFs.Extent(); aNbCBP=aCBP.Extent(); // aNbS=aDS.NumberOfShapesOfTheObject(); for (nF=1; nF<=aNbS; ++nF) { if (aDS.GetShapeType(nF)!=TopAbs_FACE) { continue; } // aF=TopoDS::Face(aDS.Shape(nF)); // aMFence.Clear(); aLSpIn.Clear(); // // 1. In Parts for (j=1; j<=aNbCBP; ++j) { NMTTools_ListOfCommonBlock& aLCB=aCBP(j); aItCB.Initialize(aLCB); for (; aItCB.More(); aItCB.Next()) { NMTTools_CommonBlock& aCB=aItCB.Value(); if (aCB.IsPaveBlockOnFace(nF)) { const BOPTools_PaveBlock& aPB1=aCB.PaveBlock1(); nSpIn=aPB1.Edge(); const TopoDS_Shape& aSpIn=aDS.Shape(nSpIn); if (aMFence.Add(aSpIn)){ aLSpIn.Append(aSpIn); } } } } // // 2. Section Parts for (j=1; j<=aNbFFs; ++j) { BOPTools_SSInterference& aFF=aFFs(j); aFF.Indices(n1, n2); if (!(n1==nF || n2==nF)) { continue; } BOPTools_SequenceOfCurves& aSC=aFF.Curves(); aNbCurves=aSC.Length(); if (!aNbCurves) { continue; } // const BOPTools_Curve& aBC=aSC(1); const BOPTools_ListOfPaveBlock& aLPB=aBC.NewPaveBlocks(); aItPB.Initialize(aLPB); for (; aItPB.More(); aItPB.Next()) { const BOPTools_PaveBlock& aPBSc=aItPB.Value(); nSpSc=aPBSc.Edge(); const TopoDS_Shape& aSpSc=aDS.Shape(nSpSc); if (aMFence.Add(aSpSc)){ aLSpIn.Append(aSpSc); } } } aNbSpIn=aLSpIn.Extent(); if (aNbSpIn) { myInParts.Add(aF, aLSpIn); } }//for (nF=1; nF<=aNbS; ++nF) { }
bool NETGENPlugin_NETGEN_2D_ONLY::Evaluate(SMESH_Mesh& aMesh, const TopoDS_Shape& aShape, MapShapeNbElems& aResMap) { TopoDS_Face F = TopoDS::Face(aShape); if(F.IsNull()) return false; // collect info from edges int nb0d = 0, nb1d = 0; bool IsQuadratic = false; bool IsFirst = true; double fullLen = 0.0; TopTools_MapOfShape tmpMap; for (TopExp_Explorer exp(F, TopAbs_EDGE); exp.More(); exp.Next()) { TopoDS_Edge E = TopoDS::Edge(exp.Current()); if( tmpMap.Contains(E) ) continue; tmpMap.Add(E); SMESH_subMesh *aSubMesh = aMesh.GetSubMesh(exp.Current()); MapShapeNbElemsItr anIt = aResMap.find(aSubMesh); if( anIt==aResMap.end() ) { SMESH_subMesh *sm = aMesh.GetSubMesh(F); SMESH_ComputeErrorPtr& smError = sm->GetComputeError(); smError.reset( new SMESH_ComputeError(COMPERR_ALGO_FAILED,"Submesh can not be evaluated",this)); return false; } std::vector<int> aVec = (*anIt).second; nb0d += aVec[SMDSEntity_Node]; nb1d += Max(aVec[SMDSEntity_Edge],aVec[SMDSEntity_Quad_Edge]); double aLen = SMESH_Algo::EdgeLength(E); fullLen += aLen; if(IsFirst) { IsQuadratic = (aVec[SMDSEntity_Quad_Edge] > aVec[SMDSEntity_Edge]); IsFirst = false; } } tmpMap.Clear(); // compute edge length double ELen = 0; if (_hypLengthFromEdges || (!_hypLengthFromEdges && !_hypMaxElementArea)) { if ( nb1d > 0 ) ELen = fullLen / nb1d; } if ( _hypMaxElementArea ) { double maxArea = _hypMaxElementArea->GetMaxArea(); ELen = sqrt(2. * maxArea/sqrt(3.0)); } GProp_GProps G; BRepGProp::SurfaceProperties(F,G); double anArea = G.Mass(); const int hugeNb = numeric_limits<int>::max()/10; if ( anArea / hugeNb > ELen*ELen ) { SMESH_subMesh *sm = aMesh.GetSubMesh(F); SMESH_ComputeErrorPtr& smError = sm->GetComputeError(); smError.reset( new SMESH_ComputeError(COMPERR_ALGO_FAILED,"Submesh can not be evaluated.\nToo small element length",this)); return false; } int nbFaces = (int) ( anArea / ( ELen*ELen*sqrt(3.) / 4 ) ); int nbNodes = (int) ( ( nbFaces*3 - (nb1d-1)*2 ) / 6 + 1 ); std::vector<int> aVec(SMDSEntity_Last); for(int i=SMDSEntity_Node; i<SMDSEntity_Last; i++) aVec[i]=0; if( IsQuadratic ) { aVec[SMDSEntity_Node] = nbNodes; aVec[SMDSEntity_Quad_Triangle] = nbFaces; } else { aVec[SMDSEntity_Node] = nbNodes; aVec[SMDSEntity_Triangle] = nbFaces; } SMESH_subMesh *sm = aMesh.GetSubMesh(F); aResMap.insert(std::make_pair(sm,aVec)); return true; }
//======================================================================= //function : FindFacePairs //purpose : //======================================================================= Standard_Boolean FindFacePairs (const TopoDS_Edge& theE, const TopTools_ListOfShape& thLF, NMTTools_ListOfCoupleOfShape& theLCFF) { Standard_Boolean bFound; Standard_Integer i, aNbCEF; TopAbs_Orientation aOr, aOrC; TopTools_MapOfShape aMFP; TopoDS_Face aF1, aF2; TopoDS_Edge aEL, aE1; TopTools_ListIteratorOfListOfShape aItLF; NMTTools_CoupleOfShape aCEF, aCFF; NMTTools_ListOfCoupleOfShape aLCEF, aLCEFx; NMTTools_ListIteratorOfListOfCoupleOfShape aIt; // bFound=Standard_True; // // Preface aLCEF aItLF.Initialize(thLF); for (; aItLF.More(); aItLF.Next()) { const TopoDS_Face& aFL=TopoDS::Face(aItLF.Value()); // bFound=GEOMAlgo_Tools3D::GetEdgeOnFace(theE, aFL, aEL); if (!bFound) { return bFound; // it can not be so } // aCEF.SetShape1(aEL); aCEF.SetShape2(aFL); aLCEF.Append(aCEF); } // aNbCEF=aLCEF.Extent(); while(aNbCEF) { // // aLCEFx aLCEFx.Clear(); aIt.Initialize(aLCEF); for (i=0; aIt.More(); aIt.Next(), ++i) { const NMTTools_CoupleOfShape& aCSx=aIt.Value(); const TopoDS_Shape& aEx=aCSx.Shape1(); const TopoDS_Shape& aFx=aCSx.Shape2(); // aOr=aEx.Orientation(); // if (!i) { aOrC=TopAbs::Reverse(aOr); aE1=TopoDS::Edge(aEx); aF1=TopoDS::Face(aFx); aMFP.Add(aFx); continue; } // if (aOr==aOrC) { aLCEFx.Append(aCSx); aMFP.Add(aFx); } } // // F2 GEOMAlgo_Tools3D::GetFaceOff(aE1, aF1, aLCEFx, aF2); // aCFF.SetShape1(aF1); aCFF.SetShape2(aF2); theLCFF.Append(aCFF); // aMFP.Add(aF1); aMFP.Add(aF2); // // refine aLCEF aLCEFx.Clear(); aLCEFx=aLCEF; aLCEF.Clear(); aIt.Initialize(aLCEFx); for (; aIt.More(); aIt.Next()) { const NMTTools_CoupleOfShape& aCSx=aIt.Value(); const TopoDS_Shape& aFx=aCSx.Shape2(); if (!aMFP.Contains(aFx)) { aLCEF.Append(aCSx); } } // aNbCEF=aLCEF.Extent(); }//while(aNbCEF) { // return bFound; }
bool NETGENPlugin_Mesher::fillNgMesh(netgen::OCCGeometry& occgeom, netgen::Mesh& ngMesh, vector<SMDS_MeshNode*>& nodeVec, const list< SMESH_subMesh* > & meshedSM) { TNode2IdMap nodeNgIdMap; TopTools_MapOfShape visitedShapes; SMESH_MesherHelper helper (*_mesh); int faceID = occgeom.fmap.Extent(); _faceDescriptors.clear(); list< SMESH_subMesh* >::const_iterator smIt, smEnd = meshedSM.end(); for ( smIt = meshedSM.begin(); smIt != smEnd; ++smIt ) { SMESH_subMesh* sm = *smIt; if ( !visitedShapes.Add( sm->GetSubShape() )) continue; SMESHDS_SubMesh * smDS = sm->GetSubMeshDS(); switch ( sm->GetSubShape().ShapeType() ) { case TopAbs_EDGE: { // EDGE // ---------------------- const TopoDS_Edge& geomEdge = TopoDS::Edge( sm->GetSubShape() ); // Add ng segments for each not meshed face the edge bounds TopTools_MapOfShape visitedAncestors; const TopTools_ListOfShape& ancestors = _mesh->GetAncestors( geomEdge ); TopTools_ListIteratorOfListOfShape ancestorIt ( ancestors ); for ( ; ancestorIt.More(); ancestorIt.Next() ) { const TopoDS_Shape & ans = ancestorIt.Value(); if ( ans.ShapeType() != TopAbs_FACE || !visitedAncestors.Add( ans )) continue; const TopoDS_Face& face = TopoDS::Face( ans ); int faceID = occgeom.fmap.FindIndex( face ); if ( faceID < 1 ) continue; // meshed face // find out orientation of geomEdge within face bool isForwad = false; for ( TopExp_Explorer exp( face, TopAbs_EDGE ); exp.More(); exp.Next() ) { if ( geomEdge.IsSame( exp.Current() )) { isForwad = ( exp.Current().Orientation() == geomEdge.Orientation() ); break; } } bool isQuad = smDS->GetElements()->next()->IsQuadratic(); // get all nodes from geomEdge StdMeshers_FaceSide fSide( face, geomEdge, _mesh, isForwad, isQuad ); const vector<UVPtStruct>& points = fSide.GetUVPtStruct(); int i, nbSeg = fSide.NbSegments(); double otherSeamParam = 0; helper.SetSubShape( face ); bool isSeam = helper.IsRealSeam( geomEdge ); if ( isSeam ) otherSeamParam = helper.GetOtherParam( helper.GetPeriodicIndex() == 1 ? points[0].u : points[0].v ); // add segments int prevNgId = ngNodeId( points[0].node, ngMesh, nodeNgIdMap ); for ( i = 0; i < nbSeg; ++i ) { const UVPtStruct& p1 = points[ i ]; const UVPtStruct& p2 = points[ i+1 ]; netgen::Segment seg; // ng node ids seg.pnums[0] = prevNgId; seg.pnums[1] = prevNgId = ngNodeId( p2.node, ngMesh, nodeNgIdMap ); // node param on curve seg.epgeominfo[ 0 ].dist = p1.param; seg.epgeominfo[ 1 ].dist = p2.param; // uv on face seg.epgeominfo[ 0 ].u = p1.u; seg.epgeominfo[ 0 ].v = p1.v; seg.epgeominfo[ 1 ].u = p2.u; seg.epgeominfo[ 1 ].v = p2.v; //seg.epgeominfo[ iEnd ].edgenr = edgeID; // = geom.emap.FindIndex(edge); seg.si = faceID; // = geom.fmap.FindIndex (face); seg.edgenr = ngMesh.GetNSeg() + 1; // segment id ngMesh.AddSegment (seg); if ( isSeam ) { if ( helper.GetPeriodicIndex() == 1 ) { seg.epgeominfo[ 0 ].u = otherSeamParam; seg.epgeominfo[ 1 ].u = otherSeamParam; swap (seg.epgeominfo[0].v, seg.epgeominfo[1].v); } else { seg.epgeominfo[ 0 ].v = otherSeamParam; seg.epgeominfo[ 1 ].v = otherSeamParam; swap (seg.epgeominfo[0].u, seg.epgeominfo[1].u); } swap (seg.pnums[0], seg.pnums[1]); swap (seg.epgeominfo[0].dist, seg.epgeominfo[1].dist); seg.edgenr = ngMesh.GetNSeg() + 1; // segment id ngMesh.AddSegment (seg); } } } // loop on geomEdge ancestors break; } // case TopAbs_EDGE case TopAbs_FACE: { // FACE // ---------------------- const TopoDS_Face& geomFace = TopoDS::Face( sm->GetSubShape() ); helper.SetSubShape( geomFace ); // Find solids the geomFace bounds int solidID1 = 0, solidID2 = 0; const TopTools_ListOfShape& ancestors = _mesh->GetAncestors( geomFace ); TopTools_ListIteratorOfListOfShape ancestorIt ( ancestors ); for ( ; ancestorIt.More(); ancestorIt.Next() ) { const TopoDS_Shape & solid = ancestorIt.Value(); if ( solid.ShapeType() == TopAbs_SOLID ) { int id = occgeom.somap.FindIndex ( solid ); if ( solidID1 && id != solidID1 ) solidID2 = id; else solidID1 = id; } } faceID++; _faceDescriptors[ faceID ].first = solidID1; _faceDescriptors[ faceID ].second = solidID2; // Orient the face correctly in solidID1 (issue 0020206) bool reverse = false; if ( solidID1 ) { TopoDS_Shape solid = occgeom.somap( solidID1 ); for ( TopExp_Explorer f( solid, TopAbs_FACE ); f.More(); f.Next() ) { if ( geomFace.IsSame( f.Current() )) { reverse = SMESH_Algo::IsReversedSubMesh( TopoDS::Face( f.Current()), helper.GetMeshDS() ); break; } } } // Add surface elements SMDS_ElemIteratorPtr faces = smDS->GetElements(); while ( faces->more() ) { const SMDS_MeshElement* f = faces->next(); if ( f->NbNodes() % 3 != 0 ) { // not triangle for ( ancestorIt.Initialize(ancestors); ancestorIt.More(); ancestorIt.Next() ) if ( ancestorIt.Value().ShapeType() == TopAbs_SOLID ) { sm = _mesh->GetSubMesh( ancestorIt.Value() ); break; } SMESH_ComputeErrorPtr& smError = sm->GetComputeError(); smError.reset( new SMESH_ComputeError(COMPERR_BAD_INPUT_MESH,"Not triangle submesh")); smError->myBadElements.push_back( f ); return false; } netgen::Element2d tri(3); tri.SetIndex ( faceID ); for ( int i = 0; i < 3; ++i ) { const SMDS_MeshNode* node = f->GetNode( i ), * inFaceNode=0; if ( helper.IsSeamShape( node->GetPosition()->GetShapeId() )) { if ( helper.IsSeamShape( f->GetNodeWrap( i+1 )->GetPosition()->GetShapeId() )) { inFaceNode = f->GetNodeWrap( i-1 ); } else { inFaceNode = f->GetNodeWrap( i+1 ); } } gp_XY uv = helper.GetNodeUV( geomFace, node, inFaceNode ); if ( reverse ) { tri.GeomInfoPi(3-i).u = uv.X(); tri.GeomInfoPi(3-i).v = uv.Y(); tri.PNum (3-i) = ngNodeId( node, ngMesh, nodeNgIdMap ); } else { tri.GeomInfoPi(i+1).u = uv.X(); tri.GeomInfoPi(i+1).v = uv.Y(); tri.PNum (i+1) = ngNodeId( node, ngMesh, nodeNgIdMap ); } } ngMesh.AddSurfaceElement (tri); } break; } // case TopAbs_VERTEX: { // VERTEX // -------------------------- SMDS_NodeIteratorPtr nodeIt = smDS->GetNodes(); if ( nodeIt->more() ) ngNodeId( nodeIt->next(), ngMesh, nodeNgIdMap ); break; } default:; } // switch } // loop on submeshes // fill nodeVec nodeVec.resize( ngMesh.GetNP() + 1 ); TNode2IdMap::iterator node_NgId, nodeNgIdEnd = nodeNgIdMap.end(); for ( node_NgId = nodeNgIdMap.begin(); node_NgId != nodeNgIdEnd; ++node_NgId) nodeVec[ node_NgId->second ] = (SMDS_MeshNode*) node_NgId->first; return true; }
//======================================================================= // function: FillImagesContainers // purpose: //======================================================================= void GEOMAlgo_Builder::FillImagesContainers(const TopAbs_ShapeEnum theType) { myErrorStatus=0; // Standard_Boolean bInterferred, bToReverse; Standard_Integer i, aNbS; TopAbs_ShapeEnum aType; BRep_Builder aBB; TopoDS_Iterator aIt; TopTools_ListIteratorOfListOfShape aItIm; TopTools_MapOfShape aMS; TopTools_MapIteratorOfMapOfShape aItS; // const NMTDS_ShapesDataStructure& aDS=*myPaveFiller->DS(); NMTTools_PaveFiller* pPF=myPaveFiller; const Handle(IntTools_Context)& aCtx= pPF->Context(); // aNbS=aDS.NumberOfShapesOfTheObject(); for (i=1; i<=aNbS; ++i) { const TopoDS_Shape& aC=aDS.Shape(i); aType=aC.ShapeType(); if (aType==theType) { aMS.Add(aC); } } // if (theType==TopAbs_COMPOUND) { FillImagesCompounds(aMS, myImages); return; } // aItS.Initialize(aMS); for (; aItS.More(); aItS.Next()) { const TopoDS_Shape& aC=aItS.Key(); // whether the shape has image bInterferred=Standard_False; aIt.Initialize(aC); for (; aIt.More(); aIt.Next()) { const TopoDS_Shape& aF=aIt.Value(); if (myImages.HasImage(aF)) { bInterferred=!bInterferred; break; } } if (!bInterferred) { continue; } // TopoDS_Shape aCIm; GEOMAlgo_Tools3D::MakeContainer(theType, aCIm); // aIt.Initialize(aC); for (; aIt.More(); aIt.Next()) { const TopoDS_Shape& aF=aIt.Value(); if (myImages.HasImage(aF)) { const TopTools_ListOfShape& aLFIm=myImages.Image(aF); aItIm.Initialize(aLFIm); for (; aItIm.More(); aItIm.Next()) { TopoDS_Shape aFIm=aItIm.Value(); // bToReverse=GEOMAlgo_Tools3D::IsSplitToReverse(aFIm, aF, aCtx); if (bToReverse) { aFIm.Reverse(); } aBB.Add(aCIm, aFIm); } } else { aBB.Add(aCIm, aF); } } myImages.Bind(aC, aCIm); }// for (; aItS.More(); aItS.Next()) { }
//======================================================================= // function: FillInternalVertices // purpose: //======================================================================= void GEOMAlgo_Builder::FillInternalVertices() { const NMTDS_ShapesDataStructure& aDS=*myPaveFiller->DS(); NMTTools_PaveFiller* pPF=myPaveFiller; NMTDS_InterfPool* pIP=pPF->IP(); IntTools_Context& aCtx= pPF->ChangeContext(); // /*BOPTools_CArray1OfSSInterference& aFFs=*/pIP->SSInterferences(); 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) { }
bool NETGENPlugin_NETGEN_3D::Evaluate(SMESH_Mesh& aMesh, const TopoDS_Shape& aShape, MapShapeNbElems& aResMap) { int nbtri = 0, nbqua = 0; double fullArea = 0.0; for (TopExp_Explorer exp(aShape, TopAbs_FACE); exp.More(); exp.Next()) { TopoDS_Face F = TopoDS::Face( exp.Current() ); SMESH_subMesh *sm = aMesh.GetSubMesh(F); MapShapeNbElemsItr anIt = aResMap.find(sm); if( anIt==aResMap.end() ) { SMESH_ComputeErrorPtr& smError = sm->GetComputeError(); smError.reset( new SMESH_ComputeError(COMPERR_ALGO_FAILED,"Submesh can not be evaluated",this)); return false; } std::vector<int> aVec = (*anIt).second; nbtri += Max(aVec[SMDSEntity_Triangle],aVec[SMDSEntity_Quad_Triangle]); nbqua += Max(aVec[SMDSEntity_Quadrangle],aVec[SMDSEntity_Quad_Quadrangle]); GProp_GProps G; BRepGProp::SurfaceProperties(F,G); double anArea = G.Mass(); fullArea += anArea; } // collect info from edges int nb0d_e = 0, nb1d_e = 0; bool IsQuadratic = false; bool IsFirst = true; TopTools_MapOfShape tmpMap; for (TopExp_Explorer exp(aShape, TopAbs_EDGE); exp.More(); exp.Next()) { TopoDS_Edge E = TopoDS::Edge(exp.Current()); if( tmpMap.Contains(E) ) continue; tmpMap.Add(E); SMESH_subMesh *aSubMesh = aMesh.GetSubMesh(exp.Current()); MapShapeNbElemsItr anIt = aResMap.find(aSubMesh); if( anIt==aResMap.end() ) { SMESH_ComputeErrorPtr& smError = aSubMesh->GetComputeError(); smError.reset( new SMESH_ComputeError(COMPERR_ALGO_FAILED, "Submesh can not be evaluated",this)); return false; } std::vector<int> aVec = (*anIt).second; nb0d_e += aVec[SMDSEntity_Node]; nb1d_e += Max(aVec[SMDSEntity_Edge],aVec[SMDSEntity_Quad_Edge]); if(IsFirst) { IsQuadratic = (aVec[SMDSEntity_Quad_Edge] > aVec[SMDSEntity_Edge]); IsFirst = false; } } tmpMap.Clear(); double ELen_face = sqrt(2.* ( fullArea/(nbtri+nbqua*2) ) / sqrt(3.0) ); double ELen_vol = pow( 72, 1/6. ) * pow( _maxElementVolume, 1/3. ); double ELen = Min(ELen_vol,ELen_face*2); GProp_GProps G; BRepGProp::VolumeProperties(aShape,G); double aVolume = G.Mass(); double tetrVol = 0.1179*ELen*ELen*ELen; double CoeffQuality = 0.9; int nbVols = (int)aVolume/tetrVol/CoeffQuality; int nb1d_f = (nbtri*3 + nbqua*4 - nb1d_e) / 2; int nb1d_in = (int) ( nbVols*6 - nb1d_e - nb1d_f ) / 5; std::vector<int> aVec(SMDSEntity_Last); for(int i=SMDSEntity_Node; i<SMDSEntity_Last; i++) aVec[i]=0; if( IsQuadratic ) { aVec[SMDSEntity_Node] = nb1d_in/6 + 1 + nb1d_in; aVec[SMDSEntity_Quad_Tetra] = nbVols - nbqua*2; aVec[SMDSEntity_Quad_Pyramid] = nbqua; } else { aVec[SMDSEntity_Node] = nb1d_in/6 + 1; aVec[SMDSEntity_Tetra] = nbVols - nbqua*2; aVec[SMDSEntity_Pyramid] = nbqua; } SMESH_subMesh *sm = aMesh.GetSubMesh(aShape); aResMap.insert(std::make_pair(sm,aVec)); return true; }
//======================================================================= //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; }