//---------------------------------------------------------------- // Function: to update the core Surface // for any movement or Boolean operation of the body. // Author: Jane Hu //---------------------------------------------------------------- CubitStatus OCCSurface::update_OCC_entity( BRepBuilderAPI_Transform *aBRepTrsf, BRepAlgoAPI_BooleanOperation *op) { assert(aBRepTrsf != NULL || op != NULL); TopoDS_Shape shape; if (aBRepTrsf) shape = aBRepTrsf->ModifiedShape(*get_TopoDS_Face()); else { TopTools_ListOfShape shapes; shapes.Assign(op->Modified(*get_TopoDS_Face())); if(shapes.Extent() == 0) shapes.Assign(op->Generated(*get_TopoDS_Face())); if (shapes.Extent() == 1) shape = shapes.First(); else if(shapes.Extent() > 1) { //update all attributes first. TopTools_ListIteratorOfListOfShape it; it.Initialize(shapes); for(; it.More(); it.Next()) { shape = it.Value(); OCCQueryEngine::instance()->copy_attributes(*get_TopoDS_Face(), shape); } shape = shapes.First(); } else if(op->IsDeleted(*get_TopoDS_Face())) ; else return CUBIT_SUCCESS; } TopoDS_Face surface; if(!shape.IsNull()) surface = TopoDS::Face(shape); if (aBRepTrsf) { //set the loops DLIList<OCCLoop *> loops; this->get_loops(loops); for (int i = 1; i <= loops.size(); i++) { OCCLoop *loop = loops.get_and_step(); loop->update_OCC_entity(aBRepTrsf, op); } OCCQueryEngine::instance()->update_OCC_map(*myTopoDSFace, surface); } else if(op) update_OCC_entity(*myTopoDSFace, surface, op); return CUBIT_SUCCESS; }
//======================================================================= // function: IsExistingPaveBlock // purpose: //======================================================================= Standard_Boolean NMTTools_PaveFiller::IsExistingPaveBlock(const BOPTools_PaveBlock& aPBNew, const TopTools_ListOfShape& aLSE, const Standard_Real aTolR3D) { Standard_Boolean bFlag; Standard_Integer aNbSE, iC; Standard_Real aTolE, aTol; TopTools_ListIteratorOfListOfShape anIt; // bFlag=Standard_False; // aNbSE=aLSE.Extent(); if (!aNbSE) { return bFlag; } // anIt.Initialize(aLSE); for (; anIt.More(); anIt.Next()) { const TopoDS_Edge& aE=TopoDS::Edge(anIt.Value()); aTolE=BRep_Tool::Tolerance(aE); aTol=aTolR3D; if (aTolE>aTol) { aTol=aTolE; } iC=CheckIntermediatePoint(aPBNew, aE, aTol); if (!iC) { return !bFlag; } } return bFlag; }
//======================================================================= // function: FillImagesFaces1 // purpose: //======================================================================= void GEOMAlgo_Builder::FillImagesFaces1() { Standard_Integer i, aNb, iSense, aNbLFx; TopoDS_Face aF, aFSp, aFSD; TopTools_ListOfShape aLFx; TopTools_ListIteratorOfListOfShape aIt; // const NMTDS_ShapesDataStructure& aDS=*myPaveFiller->DS(); // aNb=aDS.NumberOfShapesOfTheObject(); for (i=1; i<=aNb; ++i) { const TopoDS_Shape& aS=aDS.Shape(i); if (aS.ShapeType()!=TopAbs_FACE) { continue; } // if (!mySplitFaces.HasImage(aS)) { continue; } // aF=*((TopoDS_Face*)&aS); // aLFx.Clear(); const TopTools_ListOfShape& aLF=mySplitFaces.Image(aF); aIt.Initialize(aLF); for (; aIt.More(); aIt.Next()) { aFSp=*((TopoDS_Face*)(&aIt.Value())); if (!mySameDomainShapes.Contains(aFSp)) { aLFx.Append(aFSp); } else { const TopoDS_Shape& aSx=mySameDomainShapes.FindFromKey(aFSp); aFSD=*((TopoDS_Face*)(&aSx)); iSense=GEOMAlgo_Tools3D::Sense(aFSp, aFSD); if (iSense<0) { aFSD.Reverse(); } aLFx.Append(aFSD); } } // if (!myImages.HasImage(aF)) { aNbLFx=aLFx.Extent(); if (aNbLFx==1) { const TopoDS_Shape& aFx=aLFx.First(); if (aF.IsSame(aFx)) { continue; } } myImages.Bind(aF, aLFx); } } }
//======================================================================= //function : IsInternalFace //purpose : //======================================================================= Standard_Boolean GEOMAlgo_Tools3D::IsInternalFace(const TopoDS_Face& theFace, const TopoDS_Edge& theEdge, const TopTools_ListOfShape& theLF, IntTools_Context& theContext) { Standard_Boolean bRet; Standard_Boolean aNbF; // bRet=Standard_False; // aNbF=theLF.Extent(); if (aNbF==2) { const TopoDS_Face& aF1=TopoDS::Face(theLF.First()); const TopoDS_Face& aF2=TopoDS::Face(theLF.Last()); bRet=GEOMAlgo_Tools3D::IsInternalFace(theFace, theEdge, aF1, aF2, theContext); return bRet; } // else { NMTTools_ListOfCoupleOfShape aLCFF; NMTTools_ListIteratorOfListOfCoupleOfShape aIt; // FindFacePairs(theEdge, theLF, aLCFF); // aIt.Initialize(aLCFF); for (; aIt.More(); aIt.Next()) { const NMTTools_CoupleOfShape& aCSFF=aIt.Value(); // const TopoDS_Face& aF1=TopoDS::Face(aCSFF.Shape1()); const TopoDS_Face& aF2=TopoDS::Face(aCSFF.Shape2()); bRet=GEOMAlgo_Tools3D::IsInternalFace(theFace, theEdge, aF1, aF2, theContext); if (bRet) { return bRet; } } } return bRet; }
//======================================================================= // 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: 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 BOPTools_ListOfPaveBlock aLPBIn; // pPF->RealSplitsInFace(nF, aLPBIn); // aItPB.Initialize(aLPBIn); for (; aItPB.More(); aItPB.Next()) { const BOPTools_PaveBlock& aPB1=aItPB.Value(); nSpIn=aPB1.Edge(); const TopoDS_Shape& aSpIn=aDS.Shape(nSpIn); 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) { }
//======================================================================= //function : SortShapes //purpose : //======================================================================= void GEOMUtils::SortShapes (TopTools_ListOfShape& SL, const Standard_Boolean isOldSorting) { #ifdef STD_SORT_ALGO std::vector<TopoDS_Shape> aShapesVec; aShapesVec.reserve(SL.Extent()); TopTools_ListIteratorOfListOfShape it (SL); for (; it.More(); it.Next()) { aShapesVec.push_back(it.Value()); } SL.Clear(); CompareShapes shComp (isOldSorting); std::stable_sort(aShapesVec.begin(), aShapesVec.end(), shComp); //std::sort(aShapesVec.begin(), aShapesVec.end(), shComp); std::vector<TopoDS_Shape>::const_iterator anIter = aShapesVec.begin(); for (; anIter != aShapesVec.end(); ++anIter) { SL.Append(*anIter); } #else // old implementation Standard_Integer MaxShapes = SL.Extent(); TopTools_Array1OfShape aShapes (1,MaxShapes); TColStd_Array1OfInteger OrderInd(1,MaxShapes); TColStd_Array1OfReal MidXYZ (1,MaxShapes); //X,Y,Z; TColStd_Array1OfReal Length (1,MaxShapes); //X,Y,Z; // Computing of CentreOfMass Standard_Integer Index; GProp_GProps GPr; gp_Pnt GPoint; TopTools_ListIteratorOfListOfShape it(SL); for (Index=1; it.More(); Index++) { TopoDS_Shape S = it.Value(); SL.Remove( it ); // == it.Next() aShapes(Index) = S; OrderInd.SetValue (Index, Index); if (S.ShapeType() == TopAbs_VERTEX) { GPoint = BRep_Tool::Pnt( TopoDS::Vertex( S )); Length.SetValue( Index, (Standard_Real) S.Orientation()); } else { // BEGIN: fix for Mantis issue 0020842 if (isOldSorting) { BRepGProp::LinearProperties (S, GPr); } else { if (S.ShapeType() == TopAbs_EDGE || S.ShapeType() == TopAbs_WIRE) { BRepGProp::LinearProperties (S, GPr); } else if (S.ShapeType() == TopAbs_FACE || S.ShapeType() == TopAbs_SHELL) { BRepGProp::SurfaceProperties(S, GPr); } else { BRepGProp::VolumeProperties(S, GPr); } } // END: fix for Mantis issue 0020842 GPoint = GPr.CentreOfMass(); Length.SetValue(Index, GPr.Mass()); } MidXYZ.SetValue(Index, GPoint.X()*999.0 + GPoint.Y()*99.0 + GPoint.Z()*0.9); //cout << Index << " L: " << Length(Index) << "CG: " << MidXYZ(Index) << endl; } // Sorting Standard_Integer aTemp; Standard_Boolean exchange, Sort = Standard_True; Standard_Real tol = Precision::Confusion(); while (Sort) { Sort = Standard_False; for (Index=1; Index < MaxShapes; Index++) { exchange = Standard_False; Standard_Real dMidXYZ = MidXYZ(OrderInd(Index)) - MidXYZ(OrderInd(Index+1)); Standard_Real dLength = Length(OrderInd(Index)) - Length(OrderInd(Index+1)); if ( dMidXYZ >= tol ) { // cout << "MidXYZ: " << MidXYZ(OrderInd(Index))<< " > " <<MidXYZ(OrderInd(Index+1)) // << " d: " << dMidXYZ << endl; exchange = Standard_True; } else if ( Abs(dMidXYZ) < tol && dLength >= tol ) { // cout << "Length: " << Length(OrderInd(Index))<< " > " <<Length(OrderInd(Index+1)) // << " d: " << dLength << endl; exchange = Standard_True; } else if ( Abs(dMidXYZ) < tol && Abs(dLength) < tol && aShapes(OrderInd(Index)).ShapeType() <= TopAbs_FACE) { // PAL17233 // equal values possible on shapes such as two halves of a sphere and // a membrane inside the sphere Bnd_Box box1,box2; BRepBndLib::Add( aShapes( OrderInd(Index) ), box1 ); if ( box1.IsVoid() ) continue; BRepBndLib::Add( aShapes( OrderInd(Index+1) ), box2 ); Standard_Real dSquareExtent = box1.SquareExtent() - box2.SquareExtent(); if ( dSquareExtent >= tol ) { // cout << "SquareExtent: " << box1.SquareExtent()<<" > "<<box2.SquareExtent() << endl; exchange = Standard_True; } else if ( Abs(dSquareExtent) < tol ) { Standard_Real aXmin, aYmin, aZmin, aXmax, aYmax, aZmax, val1, val2; box1.Get(aXmin, aYmin, aZmin, aXmax, aYmax, aZmax); val1 = (aXmin+aXmax)*999 + (aYmin+aYmax)*99 + (aZmin+aZmax)*0.9; box2.Get(aXmin, aYmin, aZmin, aXmax, aYmax, aZmax); val2 = (aXmin+aXmax)*999 + (aYmin+aYmax)*99 + (aZmin+aZmax)*0.9; //exchange = val1 > val2; if ((val1 - val2) >= tol) { exchange = Standard_True; } //cout << "box: " << val1<<" > "<<val2 << endl; } } if (exchange) { // cout << "exchange " << Index << " & " << Index+1 << endl; aTemp = OrderInd(Index); OrderInd(Index) = OrderInd(Index+1); OrderInd(Index+1) = aTemp; Sort = Standard_True; } } } for (Index=1; Index <= MaxShapes; Index++) SL.Append( aShapes( OrderInd(Index) )); #endif }
//---------------------------------------------------------------- // Function: TopoDS_Shape level function to update the core Surface // for any movement or Boolean operation of the body. // Author: Jane Hu //---------------------------------------------------------------- CubitStatus OCCSurface::update_OCC_entity(TopoDS_Face& old_surface, TopoDS_Shape& new_surface, BRepBuilderAPI_MakeShape *op, TopoDS_Vertex* removed_vertex, LocOpe_SplitShape* sp) { //set the Wires TopTools_IndexedMapOfShape M, M2; TopoDS_Shape shape, shape2, shape_edge, shape_vertex; TopExp::MapShapes(old_surface, TopAbs_WIRE, M); TopTools_ListOfShape shapes; BRepFilletAPI_MakeFillet2d* test_op = NULL; for (int ii=1; ii<=M.Extent(); ii++) { TopoDS_Wire wire = TopoDS::Wire(M(ii)); TopTools_ListOfShape shapes; if(op) { test_op = dynamic_cast<BRepFilletAPI_MakeFillet2d*>(op); if(!test_op) shapes.Assign(op->Modified(wire)); if(shapes.Extent() == 0) shapes.Assign(op->Generated(wire)); if(!new_surface.IsNull()) TopExp::MapShapes(new_surface,TopAbs_WIRE, M2); } else if(sp) shapes.Assign(sp->DescendantShapes(wire)); if (shapes.Extent() == 1) { shape = shapes.First(); if(M2.Extent() == 1) { shape2 = TopoDS::Wire(M2(1)); if(!shape.IsSame(shape2)) shape = shape2; } else if(M2.Extent() > 1) shape.Nullify(); } else if(shapes.Extent() > 1) shape.Nullify(); else if(op->IsDeleted(wire) || shapes.Extent() == 0) { TopTools_IndexedMapOfShape M_new; TopExp::MapShapes(new_surface, TopAbs_WIRE, M_new); if (M_new.Extent()== 1) shape = M_new(1); else shape.Nullify(); } else { shape = wire; continue; } //set curves BRepTools_WireExplorer Ex; for(Ex.Init(wire); Ex.More();Ex.Next()) { TopoDS_Edge edge = Ex.Current(); if(op && !test_op) { shapes.Assign(op->Modified(edge)); if(shapes.Extent() == 0) shapes.Assign(op->Generated(edge)); } else if(sp) shapes.Assign(sp->DescendantShapes(edge)); if (shapes.Extent() == 1) { //in fillet creating mothod, one edge could generated a face, so check //it here. TopAbs_ShapeEnum type = shapes.First().TShape()->ShapeType(); if(type != TopAbs_EDGE) shape_edge.Nullify(); else shape_edge = shapes.First(); } else if (shapes.Extent() > 1) { //update all attributes first. TopTools_ListIteratorOfListOfShape it; it.Initialize(shapes); for(; it.More(); it.Next()) { shape_edge = it.Value(); OCCQueryEngine::instance()->copy_attributes(edge, shape_edge); } shape_edge.Nullify(); } else if (op->IsDeleted(edge)) shape_edge.Nullify(); else if (test_op) { if(!test_op->IsModified(edge)) shape_edge = edge; else shape_edge = (test_op->Modified(edge)).First(); } else shape_edge = edge; //update vertex TopoDS_Vertex vertex = Ex.CurrentVertex(); shapes.Clear(); if(test_op) assert(removed_vertex != NULL); if(op && ! test_op ) shapes.Assign(op->Modified(vertex)); else if(sp) shapes.Assign(sp->DescendantShapes(vertex)); if (shapes.Extent() == 1) shape_vertex = shapes.First(); else if(shapes.Extent() > 1) { //update all attributes first. TopTools_ListIteratorOfListOfShape it; it.Initialize(shapes); for(; it.More(); it.Next()) { shape_vertex = it.Value(); OCCQueryEngine::instance()->copy_attributes(vertex, shape_vertex); } shape_vertex.Nullify() ; } else if(op->IsDeleted(vertex) || (test_op && vertex.IsSame( *removed_vertex))) shape_vertex.Nullify() ; else shape_vertex = vertex; if(!vertex.IsSame(shape_vertex) ) OCCQueryEngine::instance()->update_OCC_map(vertex, shape_vertex); if (!edge.IsSame(shape_edge)) OCCQueryEngine::instance()->update_OCC_map(edge, shape_edge); } if (!wire.IsSame(shape)) OCCQueryEngine::instance()->update_OCC_map(wire, shape); } double dTOL = OCCQueryEngine::instance()->get_sme_resabs_tolerance(); if (!old_surface.IsSame(new_surface)) { TopAbs_ShapeEnum shapetype = TopAbs_SHAPE; if(!new_surface.IsNull()) shapetype = new_surface.TShape()->ShapeType(); if(shapetype == TopAbs_FACE || new_surface.IsNull()) OCCQueryEngine::instance()->update_OCC_map(old_surface, new_surface); else { TopTools_IndexedMapOfShape M; TopExp::MapShapes(new_surface, TopAbs_FACE, M); TopoDS_Shape new_shape; if(M.Extent() == 1) new_shape = M(1); else if(M.Extent() > 1) { for(int i = 1; i <= M.Extent(); i++) { GProp_GProps myProps; BRepGProp::SurfaceProperties(old_surface, myProps); double orig_mass = myProps.Mass(); gp_Pnt orig_pnt = myProps.CentreOfMass(); BRepGProp::SurfaceProperties(M(i), myProps); double after_mass = myProps.Mass(); gp_Pnt after_pnt = myProps.CentreOfMass(); if(fabs(-after_mass + orig_mass) <= dTOL && orig_pnt.IsEqual(after_pnt, dTOL)) { new_shape = M(i); break; } } } OCCQueryEngine::instance()->update_OCC_map(old_surface, new_shape); } } return CUBIT_SUCCESS; }
//======================================================================= //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: 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: TopoDS_Shape level function to update the core Body // for any Boolean operation of the body. // Author: Jane Hu //---------------------------------------------------------------- CubitStatus OCCBody::update_OCC_entity(TopoDS_Shape& old_shape, TopoDS_Shape& new_shape, BRepBuilderAPI_MakeShape *op, LocOpe_SplitShape* sp) { //set the Shells TopTools_IndexedMapOfShape M; TopExp::MapShapes(old_shape, TopAbs_SOLID, M); TopTools_IndexedMapOfShape M_new; TopExp::MapShapes(new_shape, TopAbs_SOLID, M_new); TopTools_ListOfShape shapes; TopoDS_Shape shape; CubitBoolean updated = CUBIT_FALSE; if(!old_shape.IsNull() && old_shape.ShapeType() == TopAbs_COMPOUND && !new_shape.IsNull() && new_shape.ShapeType() == TopAbs_COMPOUND && !old_shape.IsSame(new_shape)) { //By updating underling solids, shells etc., the old_shape will get changed. //trying to make sure the the number of each entity in the old and new //shapes are the same, which means that nothing is delete, that we can //update the map here. Otherwise, when deleting solids, it'll delete the //the old body and create new body. This is Ok for general boolean operation //except imprint when booleans are called, usually the original body are // supposed to be kept. updated = CUBIT_TRUE; OCCQueryEngine::instance()->update_OCC_map(old_shape, new_shape); } DLIList<int> new_solid_nums; DLIList<int> unfound_nums; for(int ii=1; ii<=M.Extent(); ii++) { TopoDS_Solid solid = TopoDS::Solid(M(ii)); TopTools_ListOfShape shapes; if(op) { shapes.Assign(op->Modified(solid)); if(shapes.Extent() == 0) shapes.Assign(op->Generated(solid)); } else if(sp) shapes.Assign(sp->DescendantShapes(solid)); if (shapes.Extent() == 1) shape = shapes.First(); else if(shapes.Extent() > 1) { //update all attributes first. TopTools_ListIteratorOfListOfShape it; it.Initialize(shapes); for(; it.More(); it.Next()) { shape = it.Value(); OCCQueryEngine::instance()->copy_attributes(solid, shape); } shape = shapes.First(); } else if(op->IsDeleted(solid)) { if (M_new.Extent()== 1 && ii == 1) shape = M_new(1); else if(M_new.Extent()== 1 && ii > 1) shape.Nullify(); else if(M_new.Extent() > 1) { GProp_GProps myProps; BRepGProp::VolumeProperties(solid, myProps); double bf_mass = myProps.Mass(); gp_Pnt old_center = myProps.CentreOfMass(); CubitBoolean found = CUBIT_FALSE; for(int l = 1; l <= M_new.Extent(); l++) { BRepGProp::VolumeProperties(M_new(l), myProps); double af_mass = myProps.Mass(); double dTol = OCCQueryEngine::instance()->get_sme_resabs_tolerance(); if(fabs(bf_mass-af_mass) < dTol) //unchanged { gp_Pnt new_center = myProps.CentreOfMass(); if(new_center.IsEqual(old_center, dTol)) { found = CUBIT_TRUE; shape = M_new(l); new_solid_nums.append(l); break; } } } if(!found) { unfound_nums.append(ii); continue; } } else shape.Nullify(); } else { shape = solid; continue; } if(shapes.Extent() > 0 || (op && op->IsDeleted(solid))) OCCLump::update_OCC_entity(solid, shape, op, sp); } if( unfound_nums.size() == 1 ) { TopoDS_Solid solid = TopoDS::Solid(M(unfound_nums.get())); for(int kk = 1; kk <= M_new.Extent(); kk++) { if(!new_solid_nums.move_to(kk)) { shape = M_new(kk); break; } } OCCLump::update_OCC_entity(solid, shape, op, sp); } else if(unfound_nums.size() > 1) { shape.Nullify(); for(int kk = 1; kk <=unfound_nums.size(); kk++) { TopoDS_Solid solid = TopoDS::Solid(M(unfound_nums.get_and_step())); OCCLump::update_OCC_entity(solid, shape, op, sp); } } if(!old_shape.IsSame(new_shape) && !updated) OCCQueryEngine::instance()->update_OCC_map(old_shape, new_shape); return CUBIT_SUCCESS; }
//======================================================================= //function : SelectEdge //purpose : Find the edge <NE> connected <CE> by the vertex <CV> in the list <LE>. // <NE> Is erased of the list. If <CE> is too in the list <LE> // with the same orientation, it's erased of the list //======================================================================= static Standard_Boolean SelectEdge(const TopoDS_Face& F, const TopoDS_Edge& CE, const TopoDS_Vertex& CV, TopoDS_Edge& NE, TopTools_ListOfShape& LE) { TopTools_ListIteratorOfListOfShape itl; NE.Nullify(); for ( itl.Initialize(LE); itl.More(); itl.Next()) { if (itl.Value().IsEqual(CE)) { LE.Remove(itl); break; } } if (LE.Extent() > 1) { //-------------------------------------------------------------- // Several possible edges. // - Test the edges differents of CE //-------------------------------------------------------------- Standard_Real cf, cl, f, l; TopoDS_Face FForward = F; Handle(Geom2d_Curve) Cc, C; FForward.Orientation(TopAbs_FORWARD); Cc = BRep_Tool::CurveOnSurface(CE,FForward,cf,cl); Standard_Real dist,distmin = 100*BRep_Tool::Tolerance(CV); Standard_Real uc,u; if (CE.Orientation () == TopAbs_FORWARD) uc = cl; else uc = cf; gp_Pnt2d P2,PV = Cc->Value(uc); Standard_Real delta = FindDelta(LE,FForward); for ( itl.Initialize(LE); itl.More(); itl.Next()) { const TopoDS_Edge& E = TopoDS::Edge(itl.Value()); if (!E.IsSame(CE)) { C = BRep_Tool::CurveOnSurface(E,FForward,f,l); if (E.Orientation () == TopAbs_FORWARD) u = f; else u = l; P2 = C->Value(u); dist = PV.Distance(P2); if (dist <= distmin){ distmin = dist; } } } Standard_Real anglemax = - PI; TopoDS_Edge SelectedEdge; for ( itl.Initialize(LE); itl.More(); itl.Next()) { const TopoDS_Edge& E = TopoDS::Edge(itl.Value()); if (!E.IsSame(CE)) { C = BRep_Tool::CurveOnSurface(E,FForward,f,l); if (E.Orientation () == TopAbs_FORWARD) u = f; else u = l; P2 = C->Value(u); dist = PV.Distance(P2); if (dist <= distmin + (1./3)*delta){ gp_Pnt2d PC, P; gp_Vec2d CTg1, CTg2, Tg1, Tg2; Cc->D2(uc, PC, CTg1, CTg2); C->D2(u, P, Tg1, Tg2); Standard_Real angle; if (CE.Orientation () == TopAbs_REVERSED && E.Orientation () == TopAbs_FORWARD) { angle = CTg1.Angle(Tg1.Reversed()); } else if (CE.Orientation () == TopAbs_FORWARD && E.Orientation () == TopAbs_REVERSED) { angle = (CTg1.Reversed()).Angle(Tg1); } else if (CE.Orientation () == TopAbs_REVERSED && E.Orientation () == TopAbs_REVERSED) { angle = CTg1.Angle(Tg1); } else if (CE.Orientation () == TopAbs_FORWARD && E.Orientation () == TopAbs_FORWARD) { angle = (CTg1.Reversed()).Angle(Tg1.Reversed()); } if (angle >= anglemax) { anglemax = angle ; SelectedEdge = E; } } } } for ( itl.Initialize(LE); itl.More(); itl.Next()) { const TopoDS_Edge& E = TopoDS::Edge(itl.Value()); if (E.IsEqual(SelectedEdge)) { NE = TopoDS::Edge(E); LE.Remove(itl); break; } } } else if (LE.Extent() == 1) { NE = TopoDS::Edge(LE.First()); LE.RemoveFirst(); } else { return Standard_False; } return Standard_True; }