Back to index

salome-geom  6.5.0
NMTTools_DEProcessor.cxx
Go to the documentation of this file.
00001 // Copyright (C) 2007-2012  CEA/DEN, EDF R&D, OPEN CASCADE
00002 //
00003 // Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
00004 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
00005 //
00006 // This library is free software; you can redistribute it and/or
00007 // modify it under the terms of the GNU Lesser General Public
00008 // License as published by the Free Software Foundation; either
00009 // version 2.1 of the License.
00010 //
00011 // This library is distributed in the hope that it will be useful,
00012 // but WITHOUT ANY WARRANTY; without even the implied warranty of
00013 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00014 // Lesser General Public License for more details.
00015 //
00016 // You should have received a copy of the GNU Lesser General Public
00017 // License along with this library; if not, write to the Free Software
00018 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
00019 //
00020 // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
00021 //
00022 
00023 // File:        NMTTools_DEProcessor.cxx
00024 // Created:     Wed Sep 12 12:10:52 2001
00025 // Author:      Peter KURNEV
00026 //              <pkv@irinox>
00027 //
00028 #include <NMTTools_DEProcessor.hxx>
00029 
00030 #include <Precision.hxx>
00031 
00032 #include <TColStd_ListIteratorOfListOfInteger.hxx>
00033 #include <TColStd_ListOfInteger.hxx>
00034 
00035 #include <gp_Pnt2d.hxx>
00036 #include <gp_Pnt.hxx>
00037 #include <gp_Lin2d.hxx>
00038 
00039 #include <ElCLib.hxx>
00040 
00041 #include <Geom2d_Curve.hxx>
00042 #include <Geom2d_Line.hxx>
00043 #include <Geom2d_TrimmedCurve.hxx>
00044 #include <Geom2dAdaptor_Curve.hxx>
00045 #include <Geom2dInt_GInter.hxx>
00046 
00047 #include <IntRes2d_IntersectionPoint.hxx>
00048 
00049 #include <TopoDS_Shape.hxx>
00050 #include <TopoDS_Edge.hxx>
00051 #include <TopoDS.hxx>
00052 #include <TopoDS_Face.hxx>
00053 #include <TopoDS_Vertex.hxx>
00054 #include <TopoDS_Solid.hxx>
00055 
00056 #include <TopExp.hxx>
00057 #include <TopTools_IndexedDataMapOfShapeListOfShape.hxx>
00058 #include <TopTools_ListOfShape.hxx>
00059 #include <TopTools_ListIteratorOfListOfShape.hxx>
00060 
00061 #include <BRep_Tool.hxx>
00062 #include <BRep_Builder.hxx>
00063 
00064 #include <BRepAdaptor_Surface.hxx>
00065 
00066 #include <BooleanOperations_AncestorsSeqAndSuccessorsSeq.hxx>
00067 
00068 #include <IntTools_Tools.hxx>
00069 #include <IntTools_Context.hxx>
00070 
00071 #include <BOPTools_DEInfo.hxx>
00072 #include <BOPTools_Pave.hxx>
00073 #include <BOPTools_ListOfPave.hxx>
00074 #include <BOPTools_ListIteratorOfListOfPave.hxx>
00075 #include <BOPTools_PaveBlock.hxx>
00076 #include <BOPTools_ListOfPaveBlock.hxx>
00077 #include <BOPTools_ListIteratorOfListOfPaveBlock.hxx>
00078 #include <BOPTools_PaveBlockIterator.hxx>
00079 #include <BOPTools_SSInterference.hxx>
00080 #include <BOPTools_PavePool.hxx>
00081 #include <BOPTools_PaveSet.hxx>
00082 #include <BOPTools_Tools3D.hxx>
00083 #include <BOPTools_SequenceOfCurves.hxx>
00084 #include <BOPTools_Curve.hxx>
00085 #include <BOPTools_CArray1OfSSInterference.hxx>
00086 #include <BOPTools_SplitShapesPool.hxx>
00087 
00088 #include <NMTDS_ShapesDataStructure.hxx>
00089 #include <NMTDS_InterfPool.hxx>
00090 
00091 #include <NMTTools_PaveFiller.hxx>
00092 
00093 //=======================================================================
00094 // function:
00095 // purpose:
00096 //=======================================================================
00097   NMTTools_DEProcessor::NMTTools_DEProcessor(NMTTools_PaveFiller& aPaveFiller)
00098 :
00099   myIsDone(Standard_False)
00100 {
00101   myFiller=(NMTTools_PaveFiller*) &aPaveFiller;
00102   myDS=myFiller->DS();
00103 }
00104 //=======================================================================
00105 // function: IsDone
00106 // purpose:
00107 //=======================================================================
00108   Standard_Boolean NMTTools_DEProcessor::IsDone() const
00109 {
00110   return myIsDone;
00111 }
00112 //=======================================================================
00113 // function:  Do
00114 // purpose:
00115 //=======================================================================
00116   void NMTTools_DEProcessor::Do()
00117 {
00118   Standard_Integer aNbE;
00119   //
00120   myIsDone=Standard_False;
00121   //
00122   FindDegeneratedEdges();
00123   //
00124   aNbE=myDEMap.Extent();
00125   if (!aNbE) {
00126     myIsDone=!myIsDone;
00127     return;
00128   }
00129   //
00130   DoPaves();
00131 }
00132 //=======================================================================
00133 // function:  FindDegeneratedEdges
00134 // purpose:
00135 //=======================================================================
00136   void NMTTools_DEProcessor::FindDegeneratedEdges()
00137 {
00138   Standard_Integer i, aNb, nV, nF, nVx, ip, iRankE;
00139   TopoDS_Vertex aV;
00140   TopTools_IndexedDataMapOfShapeListOfShape aMEF;
00141   //
00142   aNb=myDS->NumberOfShapesOfTheObject();
00143   for (i=1; i<=aNb; ++i) {
00144     const TopoDS_Shape aF=myDS->Shape(i);
00145     if (aF.ShapeType()==TopAbs_FACE) {
00146       TopExp::MapShapesAndAncestors (aF, TopAbs_EDGE, TopAbs_FACE, aMEF);
00147     }
00148   }
00149   //
00150   for (i=1; i<=aNb; ++i) {
00151     const TopoDS_Shape aS=myDS->Shape(i);
00152     if (aS.ShapeType()==TopAbs_EDGE) {
00153       const TopoDS_Edge& aE=TopoDS::Edge(aS);
00154 
00155       if (BRep_Tool::Degenerated(aE)) {
00156         iRankE=myDS->Rank(i);
00157         aV=TopExp::FirstVertex(aE);
00158         nVx=myDS->ShapeIndex(aV, iRankE);
00159         //
00160         nV=nVx;
00161         ip=myFiller->FindSDVertex(nV);
00162         if (ip) {
00163           nV=ip;
00164         }
00165         //
00166         TColStd_ListOfInteger aLFn;
00167         const TopTools_ListOfShape& aLF=aMEF.FindFromKey(aE);
00168         TopTools_ListIteratorOfListOfShape anIt(aLF);
00169         for (; anIt.More(); anIt.Next()) {
00170           const TopoDS_Shape& aF=anIt.Value();
00171           nF=myDS->ShapeIndex(aF, iRankE);
00172           aLFn.Append(nF);
00173         }
00174         BOPTools_DEInfo aDEInfo;
00175         aDEInfo.SetVertex(nV);
00176         aDEInfo.SetFaces(aLFn);
00177 
00178         myDEMap.Add (i, aDEInfo);
00179       }
00180     }
00181   }
00182 }
00183 //=======================================================================
00184 // function:  DoPaves
00185 // purpose:
00186 //=======================================================================
00187   void NMTTools_DEProcessor::DoPaves()
00188 {
00189 
00190   Standard_Integer i, aNbE, nED, nVD, aNbLPB, nFD;
00191   //
00192   nFD=0;
00193   aNbE=myDEMap.Extent();
00194   for (i=1; i<=aNbE; ++i) {
00195     nED=myDEMap.FindKey(i);
00196     //
00197     const BOPTools_DEInfo& aDEInfo=myDEMap(i);
00198     nVD=aDEInfo.Vertex();
00199     //
00200     // Fill PaveSet for the edge nED
00201     const TColStd_ListOfInteger& nLF=aDEInfo.Faces();
00202     TColStd_ListIteratorOfListOfInteger anIt(nLF);
00203     for (; anIt.More(); anIt.Next()) {
00204       nFD=anIt.Value();
00205 
00206       BOPTools_ListOfPaveBlock aLPB;
00207       FindPaveBlocks(nED, nVD, nFD, aLPB);
00208       //
00209       aNbLPB=aLPB.Extent();
00210       if (!aNbLPB) {
00211         continue;
00212       }
00213       //
00214       FillPaveSet (nED, nVD, nFD, aLPB);
00215     }
00216     //
00217     // Fill aSplitEdges for the edge nED
00218     FillSplitEdgesPool(nED);
00219     //
00220     // MakeSplitEdges
00221     MakeSplitEdges(nED, nFD);
00222     //
00223   }// next nED
00224 }
00225 //=======================================================================
00226 // function:  FindPaveBlocks
00227 // purpose:
00228 //=======================================================================
00229   void NMTTools_DEProcessor::FindPaveBlocks(const Standard_Integer ,
00230                                             const Standard_Integer nVD,
00231                                             const Standard_Integer nFD,
00232                                             BOPTools_ListOfPaveBlock& aLPBOut)
00233 {
00234   BOPTools_ListIteratorOfListOfPaveBlock anIt;
00235   Standard_Integer i, aNb, nF2, nV;
00236   //
00237   BOPTools_CArray1OfSSInterference& aFFs=(myFiller->IP())->SSInterferences();
00238   //
00239   aNb=aFFs.Extent();
00240   for (i=1; i<=aNb; ++i) {
00241     BOPTools_SSInterference& aFF=aFFs(i);
00242     //
00243     nF2=aFF.OppositeIndex(nFD);
00244     if (!nF2) {
00245       continue;
00246     }
00247     //
00248     // Split Parts
00249     const BOPTools_ListOfPaveBlock& aLPBSplits=aFF.PaveBlocks();
00250     anIt.Initialize(aLPBSplits);
00251     for (; anIt.More(); anIt.Next()) {
00252       const BOPTools_PaveBlock& aPBSp=anIt.Value();
00253       //
00254       const BOPTools_Pave& aPave1=aPBSp.Pave1();
00255       nV=aPave1.Index();
00256       if (nV==nVD) {
00257         aLPBOut.Append(aPBSp);
00258         continue;
00259       }
00260       //
00261       const BOPTools_Pave& aPave2=aPBSp.Pave2();
00262       nV=aPave2.Index();
00263       if (nV==nVD) {
00264         aLPBOut.Append(aPBSp);
00265         continue;
00266       }
00267     }
00268     //
00269     // Section Parts
00270     Standard_Integer j, aNbCurves;
00271     //
00272     BOPTools_SequenceOfCurves& aSC=aFF.Curves();
00273     aNbCurves=aSC.Length();
00274     for (j=1; j<=aNbCurves; ++j) {
00275       const BOPTools_Curve& aBC=aSC(j);
00276       const BOPTools_ListOfPaveBlock& aLPBSe=aBC.NewPaveBlocks();
00277       //
00278       anIt.Initialize(aLPBSe);
00279       for (; anIt.More(); anIt.Next()) {
00280         const BOPTools_PaveBlock& aPBSe=anIt.Value();
00281         //
00282         const BOPTools_Pave& aPv1=aPBSe.Pave1();
00283         nV=aPv1.Index();
00284         if (nV==nVD) {
00285           aLPBOut.Append(aPBSe);
00286           continue;
00287         }
00288         //
00289         const BOPTools_Pave& aPv2=aPBSe.Pave2();
00290         nV=aPv2.Index();
00291         if (nV==nVD) {
00292           aLPBOut.Append(aPBSe);
00293           continue;
00294         }
00295       }
00296     }
00297   }
00298 }
00299 //=======================================================================
00300 // function:  FillPaveSet
00301 // purpose:
00302 //=======================================================================
00303   void NMTTools_DEProcessor::FillPaveSet (const Standard_Integer nED,
00304                                           const Standard_Integer nVD,
00305                                           const Standard_Integer nFD,
00306                                           const BOPTools_ListOfPaveBlock& aLPB)
00307 {
00308   Standard_Boolean bIsDone, bXDir, bRejectFlag;
00309   Standard_Integer nE, aNbPoints, j;
00310   Standard_Real aTD1, aTD2, aT1, aT2, aTolInter, aX, aDT, aXx;
00311   gp_Pnt2d aP2d1, aP2d2, aP2D;
00312   gp_Lin2d aLDE;
00313   //
00314   aDT=Precision::PConfusion();
00315   //
00316   BOPTools_PaveSet& aPaveSet=
00317     (myFiller->ChangePavePool()).ChangeValue(myDS->RefEdge(nED));
00318   //
00319   // Clear aPaveSet, aSplitEdges
00320   aPaveSet.ChangeSet().Clear();
00321   //
00322   const TopoDS_Edge aDE=TopoDS::Edge(myDS->Shape(nED));
00323   const TopoDS_Face aDF=TopoDS::Face(myDS->Shape(nFD));
00324   //
00325   // 2D Curve of degenerated edge on the face aDF
00326   Handle(Geom2d_Curve) aC2DDE1=BRep_Tool::CurveOnSurface(aDE, aDF, aTD1, aTD2);
00327   Handle(Geom2d_TrimmedCurve)aC2DDE=new Geom2d_TrimmedCurve(aC2DDE1, aTD1, aTD2);
00328   //
00329   // Choose direction for degenerated edge
00330   aC2DDE->D0(aTD1, aP2d1);
00331   aC2DDE->D0(aTD2, aP2d2);
00332 
00333   bXDir=Standard_False;
00334   if (fabs(aP2d1.Y()-aP2d2.Y()) < aDT){
00335     bXDir=!bXDir;
00336   }
00337   //
00338   // Prepare bounding Paves
00339   BOPTools_Pave aPave1 (nVD, aTD1, BooleanOperations_UnknownInterference);
00340   aPaveSet.Append(aPave1);
00341   BOPTools_Pave aPave2 (nVD, aTD2, BooleanOperations_UnknownInterference);
00342   aPaveSet.Append(aPave2);
00343   //
00344   // Fill other paves
00345   BOPTools_ListIteratorOfListOfPaveBlock anIt(aLPB);
00346   for (; anIt.More(); anIt.Next()) {
00347     const BOPTools_PaveBlock& aPB=anIt.Value();
00348     nE=aPB.Edge();
00349     const TopoDS_Edge aE=TopoDS::Edge(myDS->Shape(nE));
00350 
00351     Handle(Geom2d_Curve) aC2D=BRep_Tool::CurveOnSurface(aE, aDF, aT1, aT2);
00352     //
00353     // Intersection
00354     Geom2dAdaptor_Curve aGAC1, aGAC2;
00355     //
00356     aGAC1.Load(aC2DDE, aTD1, aTD2);
00357     Handle(Geom2d_Line) aL2D= Handle(Geom2d_Line)::DownCast(aC2D);
00358     if (!aL2D.IsNull()) {
00359       aGAC2.Load(aC2D);
00360     }
00361     else {
00362       aGAC2.Load(aC2D, aT1, aT2);
00363     }
00364     //
00365     aTolInter=0.001;
00366     Geom2dInt_GInter aGInter(aGAC1, aGAC2, aTolInter, aTolInter);
00367     bIsDone=aGInter.IsDone();
00368     if(bIsDone) {
00369       aNbPoints=aGInter.NbPoints();
00370       if (aNbPoints) {
00371         for (j=1; j<=aNbPoints; ++j) {
00372           aP2D=aGInter.Point(j).Value();
00373           Handle(Geom2d_Line) aCLDE;
00374           //
00375           //modified by NIZNHY-PKV Thu Mar 20 17:37:32 2008f
00376           Handle(Geom2d_TrimmedCurve) aCLDET1=
00377             Handle(Geom2d_TrimmedCurve)::DownCast(aC2DDE1);
00378           if (aCLDET1.IsNull()) {
00379             aCLDE=Handle(Geom2d_Line)::DownCast(aC2DDE1);
00380           }
00381           else {
00382             Handle(Geom2d_Curve) aBasisCurve=aCLDET1->BasisCurve();
00383             aCLDE=Handle(Geom2d_Line)::DownCast(aBasisCurve);
00384           }
00385           //aCLDE=Handle(Geom2d_Line)::DownCast(aC2DDE1);
00386           //modified by NIZNHY-PKV Thu Mar 20 17:37:37 2008t
00387 
00388           if (aCLDE.IsNull()) {
00389             continue;
00390           }
00391 
00392           aLDE=aCLDE->Lin2d();
00393           aX=ElCLib::Parameter(aLDE, aP2D);
00394           //
00395           if (fabs (aX-aTD1) < aDT || fabs (aX-aTD2) < aDT) {
00396             continue;
00397           }
00398           if (aX < aTD1 || aX > aTD2) {
00399             continue;
00400           }
00401           //
00402           bRejectFlag=Standard_False;
00403           const BOPTools_ListOfPave& aListOfPave=aPaveSet.Set();
00404           BOPTools_ListIteratorOfListOfPave aPaveIt(aListOfPave);
00405           for (; aPaveIt.More(); aPaveIt.Next()) {
00406             const BOPTools_Pave& aPavex=aPaveIt.Value();
00407             aXx=aPavex.Param();
00408             if (fabs (aX-aXx) < aDT) {
00409               bRejectFlag=Standard_True;
00410               break;
00411             }
00412           }
00413           if (bRejectFlag) {
00414             continue;
00415           }
00416           //
00417           BOPTools_Pave aPave(nVD, aX, BooleanOperations_UnknownInterference);
00418           aPaveSet.Append(aPave);
00419         }
00420       }
00421     }
00422   }
00423 }
00424 //=======================================================================
00425 // function:  FillSplitEdgesPool
00426 // purpose:
00427 //=======================================================================
00428   void NMTTools_DEProcessor::FillSplitEdgesPool (const Standard_Integer nED)
00429 {
00430   BOPTools_SplitShapesPool& aSplitShapesPool=
00431     myFiller->ChangeSplitShapesPool();
00432   BOPTools_ListOfPaveBlock& aSplitEdges=
00433     aSplitShapesPool.ChangeValue(myDS->RefEdge(nED));
00434   //
00435   aSplitEdges.Clear();
00436   //
00437   const BOPTools_PavePool& aPavePool=myFiller->PavePool();
00438   BOPTools_PavePool* pPavePool=(BOPTools_PavePool*) &aPavePool;
00439   BOPTools_PaveSet& aPaveSet= pPavePool->ChangeValue(myDS->RefEdge(nED));
00440 
00441   BOPTools_PaveBlockIterator aPBIt(nED, aPaveSet);
00442   for (; aPBIt.More(); aPBIt.Next()) {
00443     BOPTools_PaveBlock& aPB=aPBIt.Value();
00444     aSplitEdges.Append(aPB);
00445   }
00446 }
00447 //=======================================================================
00448 // function:  MakeSplitEdges
00449 // purpose:
00450 //=======================================================================
00451   void NMTTools_DEProcessor::MakeSplitEdges (const Standard_Integer nED,
00452                                              const Standard_Integer nFD)
00453 {
00454   const BOPTools_SplitShapesPool& aSplitShapesPool=myFiller->SplitShapesPool();
00455   const BOPTools_ListOfPaveBlock& aSplitEdges=aSplitShapesPool(myDS->RefEdge(nED));
00456 
00457   Standard_Integer nV1, nV2, aNbPB, aNewShapeIndex;
00458   Standard_Real t1, t2;
00459   TopoDS_Edge aE, aESplit;
00460   TopoDS_Vertex aV1, aV2;
00461   BOPTools_ListIteratorOfListOfPaveBlock aPBIt;
00462   //
00463   const TopoDS_Edge aDE=TopoDS::Edge(myDS->Shape(nED));
00464   const TopoDS_Face aDF=TopoDS::Face(myDS->Shape(nFD));
00465   //
00466   //modified by NIZNHY-PKV Wed Oct 20 13:20:37 2010f
00467   aNbPB=aSplitEdges.Extent();
00468   if (aNbPB==1) {
00469     Standard_Real aT1, aT2, dT1, dT2, aDT;
00470     Handle(Geom2d_Curve) aC2D;
00471     //
00472     BOPTools_PaveBlock& aPB=aSplitEdges.First();
00473     //
00474     const BOPTools_Pave& aPave1=aPB.Pave1();
00475     t1=aPave1.Param();
00476     const BOPTools_Pave& aPave2=aPB.Pave2();
00477     t2=aPave2.Param();
00479     nV1=aPave1.Index();
00480     aV1=*((TopoDS_Vertex*)&myDS->GetShape(nV1));
00481     //
00482     aV2=TopExp::FirstVertex(aDE);
00483     if (aV2.IsSame(aV1)) {
00484       aC2D=BRep_Tool::CurveOnSurface(aDE, aDF, aT1, aT2);
00485       dT1=aT1-t1;
00486       if (dT1<0.) {
00487        dT1=-dT1;
00488       }
00489       //
00490       dT2=aT2-t2;
00491       if (dT2<0.) {
00492        dT2=-dT2;
00493       }
00494       aDT=Precision::PConfusion();
00495       if(dT1<aDT && dT2<aDT) {
00496        BOPTools_ListOfPaveBlock* pLPB=(BOPTools_ListOfPaveBlock*)&aSplitEdges;
00497        pLPB->Clear();
00498        return;
00499       }
00500     }
00501   }
00502   //modified by NIZNHY-PKV Wed Oct 20 13:20:39 2010t
00503   //
00504   aPBIt.Initialize(aSplitEdges);
00505   for (; aPBIt.More(); aPBIt.Next()) {
00506     BOPTools_PaveBlock& aPB=aPBIt.Value();
00507 
00508     const BOPTools_Pave& aPave1=aPB.Pave1();
00509     nV1=aPave1.Index();
00510     t1=aPave1.Param();
00511     aV1=TopoDS::Vertex(myDS->GetShape(nV1));
00512     aV1.Orientation(TopAbs_FORWARD);
00513 
00514     const BOPTools_Pave& aPave2=aPB.Pave2();
00515     nV2=aPave2.Index();
00516     t2=aPave2.Param();
00517     aV2=TopoDS::Vertex(myDS->GetShape(nV2));
00518     aV2.Orientation(TopAbs_REVERSED);
00519 
00520     MakeSplitEdge(aDE, aDF, aV1, t1, aV2, t2, aESplit);
00521     //
00522     // Add Split Part of the Original Edge to the DS
00523     BooleanOperations_AncestorsSeqAndSuccessorsSeq anASSeq;
00524 
00525     anASSeq.SetNewSuccessor(nV1);
00526     anASSeq.SetNewOrientation(aV1.Orientation());
00527 
00528     anASSeq.SetNewSuccessor(nV2);
00529     anASSeq.SetNewOrientation(aV2.Orientation());
00530 
00531     myDS->InsertShapeAndAncestorsSuccessors(aESplit, anASSeq);
00532     aNewShapeIndex=myDS->NumberOfInsertedShapes();
00533     myDS->SetState(aNewShapeIndex, BooleanOperations_UNKNOWN);
00534     //
00535     // Fill Split Set for the Original Edge
00536     aPB.SetEdge(aNewShapeIndex);
00537     //
00538   }
00539 }
00540 //=======================================================================
00541 // function:  MakeSplitEdge
00542 // purpose:
00543 //=======================================================================
00544   void NMTTools_DEProcessor::MakeSplitEdge (const TopoDS_Edge&   aE,
00545                                             const TopoDS_Face&   aF,
00546                                             const TopoDS_Vertex& aV1,
00547                                             const Standard_Real  aP1,
00548                                             const TopoDS_Vertex& aV2,
00549                                             const Standard_Real  aP2,
00550                                             TopoDS_Edge& aNewEdge)
00551 {
00552   Standard_Real aTol=1.e-7;
00553 
00554   TopoDS_Edge E=aE;
00555 
00556   E.EmptyCopy();
00557   BRep_Builder BB;
00558   BB.Add  (E, aV1);
00559   BB.Add  (E, aV2);
00560 
00561   BB.Range(E, aF, aP1, aP2);
00562 
00563   BB.Degenerated(E, Standard_True);
00564 
00565   BB.UpdateEdge(E, aTol);
00566   aNewEdge=E;
00567 }
00568