1 // Copyright (C) 2007-2014 CEA/DEN, EDF R&D, OPEN CASCADE
3 // Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
4 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
6 // This library is free software; you can redistribute it and/or
7 // modify it under the terms of the GNU Lesser General Public
8 // License as published by the Free Software Foundation; either
9 // version 2.1 of the License, or (at your option) any later version.
11 // This library is distributed in the hope that it will be useful,
12 // but WITHOUT ANY WARRANTY; without even the implied warranty of
13 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 // Lesser General Public License for more details.
16 // You should have received a copy of the GNU Lesser General Public
17 // License along with this library; if not, write to the Free Software
18 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
20 // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
23 // File: GEOMAlgo_FinderShapeOn2.cxx
24 // Created: Fri Mar 4 10:31:06 2005
25 // Author: Peter KURNEV
28 #include <GEOMAlgo_FinderShapeOn2.hxx>
31 #include <Basics_OCCTVersion.hxx>
33 #include <Precision.hxx>
34 #include <TColStd_Array1OfInteger.hxx>
35 #include <TColStd_MapOfInteger.hxx>
37 #include <gp_Trsf.hxx>
38 #include <gp_Cylinder.hxx>
41 #include <TColgp_Array1OfPnt.hxx>
43 #include <Poly_Array1OfTriangle.hxx>
44 #include <Poly_Triangle.hxx>
45 #include <Poly_PolygonOnTriangulation.hxx>
46 #include <Poly_Triangulation.hxx>
47 #include <Poly_Polygon3D.hxx>
49 #include <Geom_Curve.hxx>
50 #include <Geom_Surface.hxx>
51 #include <GeomAdaptor_Surface.hxx>
52 #include <GeomAbs_SurfaceType.hxx>
53 #include <GeomAdaptor_Curve.hxx>
54 #include <GeomAbs_CurveType.hxx>
56 #include <TopAbs_State.hxx>
58 #include <TopLoc_Location.hxx>
60 #include <TopoDS_Shape.hxx>
61 #include <TopoDS_Vertex.hxx>
62 #include <TopoDS_Face.hxx>
63 #include <TopoDS_Edge.hxx>
66 #include <TopExp_Explorer.hxx>
68 #include <TopTools_IndexedMapOfShape.hxx>
70 #include <BRep_Tool.hxx>
71 #include <BRepLib_MakeEdge.hxx>
73 #include <GEOMAlgo_ListIteratorOfListOfPnt.hxx>
74 #include <GEOMAlgo_SurfaceTools.hxx>
75 #include <GEOMAlgo_StateCollector.hxx>
76 #include <GEOMAlgo_FinderShapeOn.hxx>
78 #include <GEOMAlgo_PassKey.hxx>
79 #include <GEOMAlgo_DataMapOfPassKeyInteger.hxx>
80 #include <GEOMAlgo_DataMapIteratorOfDataMapOfPassKeyInteger.hxx>
82 #include <gp_Dir2d.hxx>
83 #include <gp_Pnt2d.hxx>
84 #include <Geom2d_Line.hxx>
85 #include <Geom2dAdaptor_Curve.hxx>
86 #include <Geom2dHatch_Hatcher.hxx>
87 #include <TColStd_ListOfInteger.hxx>
88 #include <TColStd_ListIteratorOfListOfInteger.hxx>
89 #include <HatchGen_Domain.hxx>
90 #include <Geom2dHatch_Hatcher.hxx>
91 #if OCC_VERSION_LARGE > 0x06070100
92 #include <IntTools_Context.hxx>
94 #include <BOPInt_Context.hxx>
96 #include <BRepTools.hxx>
97 #include <IntTools_Tools.hxx>
99 //=======================================================================
102 //=======================================================================
103 GEOMAlgo_FinderShapeOn2::GEOMAlgo_FinderShapeOn2()
108 myShapeType=TopAbs_VERTEX;
109 myState=GEOMAlgo_ST_UNKNOWN;
113 //=======================================================================
116 //=======================================================================
117 GEOMAlgo_FinderShapeOn2::~GEOMAlgo_FinderShapeOn2()
120 //=======================================================================
123 //=======================================================================
124 void GEOMAlgo_FinderShapeOn2::SetClsf(const Handle(GEOMAlgo_Clsf)& aClsf)
128 //=======================================================================
131 //=======================================================================
132 const Handle(GEOMAlgo_Clsf)& GEOMAlgo_FinderShapeOn2::Clsf() const
136 //=======================================================================
137 //function : SetShapeType
139 //=======================================================================
140 void GEOMAlgo_FinderShapeOn2::SetShapeType(const TopAbs_ShapeEnum aType)
144 //=======================================================================
145 //function : ShapeType
147 //=======================================================================
148 TopAbs_ShapeEnum GEOMAlgo_FinderShapeOn2::ShapeType()const
152 //=======================================================================
153 //function : SetState
155 //=======================================================================
156 void GEOMAlgo_FinderShapeOn2::SetState(const GEOMAlgo_State aState)
160 //=======================================================================
163 //=======================================================================
164 GEOMAlgo_State GEOMAlgo_FinderShapeOn2::State() const
168 //=======================================================================
169 //function : SetNbPntsMin
171 //=======================================================================
172 void GEOMAlgo_FinderShapeOn2::SetNbPntsMin(const Standard_Integer aNb)
176 //=======================================================================
177 //function : NbPntsMin
179 //=======================================================================
180 Standard_Integer GEOMAlgo_FinderShapeOn2::NbPntsMin()const
184 //=======================================================================
185 //function : SetNbPntsMax
187 //=======================================================================
188 void GEOMAlgo_FinderShapeOn2::SetNbPntsMax(const Standard_Integer aNb)
192 //=======================================================================
193 //function : NbPntsMax
195 //=======================================================================
196 Standard_Integer GEOMAlgo_FinderShapeOn2::NbPntsMax()const
200 //=======================================================================
203 //=======================================================================
204 const GEOMAlgo_IndexedDataMapOfShapeState& GEOMAlgo_FinderShapeOn2::MSS() const
208 //=======================================================================
211 //=======================================================================
212 const TopTools_ListOfShape& GEOMAlgo_FinderShapeOn2::Shapes() const
214 Standard_Integer i, aNb;
215 TopTools_ListOfShape* pL;
217 pL=(TopTools_ListOfShape*) &myLS;
221 for (i=1; i<=aNb; ++i) {
222 const TopoDS_Shape& aS=myMSS.FindKey(i);
223 if (aS.ShapeType()==myShapeType) {
229 //=======================================================================
232 //=======================================================================
233 void GEOMAlgo_FinderShapeOn2::Perform()
245 // Initialize the context
246 GEOMAlgo_ShapeAlgo::Perform();
248 myClsf->SetTolerance(myTolerance);
255 if (myShapeType==TopAbs_VERTEX) {
264 if (myShapeType==TopAbs_EDGE) {
273 if (myShapeType==TopAbs_FACE) {
281 //=======================================================================
282 //function : CheckData
284 //=======================================================================
285 void GEOMAlgo_FinderShapeOn2::CheckData()
287 Standard_Integer iErr;
291 if(myClsf.IsNull()) {
292 myErrorStatus=10; // myClsf=NULL
297 iErr=myClsf->ErrorStatus();
299 myErrorStatus=41; // invalid data for classifier
303 if (myShape.IsNull()) {
304 myErrorStatus=11; // myShape=NULL
308 if (!(myShapeType==TopAbs_VERTEX ||
309 myShapeType==TopAbs_EDGE ||
310 myShapeType==TopAbs_FACE ||
311 myShapeType==TopAbs_SOLID)) {
312 myErrorStatus=12; // unallowed sub-shape type
316 if (myState==GEOMAlgo_ST_UNKNOWN ||
317 myState==GEOMAlgo_ST_INOUT) {
318 myErrorStatus=13; // unallowed state type
322 //=======================================================================
323 //function : ProcessVertices
325 //=======================================================================
326 void GEOMAlgo_FinderShapeOn2::ProcessVertices()
330 Standard_Boolean bIsConformState;
331 Standard_Integer i, aNb, iErr;
333 TopTools_IndexedMapOfShape aM;
336 TopExp::MapShapes(myShape, TopAbs_VERTEX, aM);
338 for (i=1; i<=aNb; ++i) {
339 const TopoDS_Vertex& aV=TopoDS::Vertex(aM(i));
340 aP=BRep_Tool::Pnt(aV);
344 iErr=myClsf->ErrorStatus();
346 myErrorStatus=40; // point can not be classified
351 bIsConformState=GEOMAlgo_SurfaceTools::IsConformState(aSt, myState);
353 if (myShapeType==TopAbs_VERTEX){
354 if (bIsConformState) {
358 else if (bIsConformState || aSt==TopAbs_ON) {
363 //=======================================================================
364 //function : ProcessEdges
366 //=======================================================================
367 void GEOMAlgo_FinderShapeOn2::ProcessEdges()
371 Standard_Boolean bIsConformState, bIsToBreak;
372 Standard_Integer i, aNb, iCnt, iErr;
374 TopTools_IndexedMapOfShape aM;
375 TopExp_Explorer aExp;
376 GEOMAlgo_ListIteratorOfListOfPnt aIt;
378 TopExp::MapShapes(myShape, TopAbs_EDGE, aM);
380 for (i=1; i<=aNb; ++i) {
381 GEOMAlgo_ListOfPnt aLP;
382 GEOMAlgo_StateCollector aSC;
384 const TopoDS_Edge& aE=TopoDS::Edge(aM(i));
386 aExp.Init(aE, TopAbs_VERTEX);
387 for (; aExp.More(); aExp.Next()) {
388 const TopoDS_Shape& aV=aExp.Current();
390 bIsConformState=myMSS.Contains(aV);
391 if (!bIsConformState) {
392 break;// vertex has non-conformed state
395 aSt=myMSS.FindFromKey(aV);
396 aSC.AppendState(aSt);
400 if (!bIsConformState) {
401 continue; // vertex has non-conformed state,skip edge
404 if (BRep_Tool::Degenerated(aE)) {
409 if (myState==GEOMAlgo_ST_ON) {
410 Standard_Boolean bCanBeON;
411 Standard_Real aT1, aT2;
412 Handle(Geom_Curve) aC;
414 aC=BRep_Tool::Curve(aE, aT1, aT2);
415 bCanBeON=myClsf->CanBeON(aC);
421 InnerPoints(aE, aLP);
426 bIsConformState=Standard_True;
428 for (iCnt=0; aIt.More(); aIt.Next(), ++iCnt) {
430 if (iCnt > myNbPntsMax) {
435 const gp_Pnt& aP=aIt.Value();
439 iErr=myClsf->ErrorStatus();
441 myErrorStatus=40; // point can not be classified
447 bIsToBreak=aSC.AppendState(aSt);
455 bIsConformState=GEOMAlgo_SurfaceTools::IsConformState(aSt, myState);
456 if (myShapeType==TopAbs_EDGE) {
457 if (bIsConformState) {
461 else if (bIsConformState || aSt==TopAbs_ON) {
464 } // for (i=1; i<=aNb; ++i) next edge
466 //=======================================================================
467 //function : ProcessFaces
469 //=======================================================================
470 void GEOMAlgo_FinderShapeOn2::ProcessFaces()
474 Standard_Boolean bIsConformState, bIsToBreak, bCanBeON;
475 Standard_Integer i, aNbF, iCnt, iErr;
477 TopTools_IndexedMapOfShape aM;
478 TopExp_Explorer aExp;
479 GEOMAlgo_ListIteratorOfListOfPnt aIt;
481 TopExp::MapShapes(myShape, TopAbs_FACE, aM);
483 for (i=1; i<=aNbF; ++i) {
484 GEOMAlgo_StateCollector aSC;
485 GEOMAlgo_ListOfPnt aLP;
487 const TopoDS_Face& aF=TopoDS::Face(aM(i));
489 if (myState==GEOMAlgo_ST_ON) {
490 Handle(Geom_Surface) aS;
492 aS=BRep_Tool::Surface(aF);
493 bCanBeON=myClsf->CanBeON(aS);
499 aExp.Init(aF, TopAbs_EDGE);
500 for (; aExp.More(); aExp.Next()) {
501 const TopoDS_Shape& aE=aExp.Current();
502 bIsConformState=myMSS.Contains(aE);
503 if (!bIsConformState) {
504 break;// edge has non-conformed state
507 aSt=myMSS.FindFromKey(aE);
508 aSC.AppendState(aSt);
512 if (!bIsConformState) {
513 continue; // edge has non-conformed state,skip face
516 InnerPoints(aF, aLP);
521 bIsConformState=Standard_True;
523 for (iCnt=0; aIt.More(); aIt.Next(), ++iCnt) {
525 if (iCnt > myNbPntsMax) {
530 const gp_Pnt& aP=aIt.Value();
534 iErr=myClsf->ErrorStatus();
536 myErrorStatus=40; // point can not be classified
542 bIsToBreak=aSC.AppendState(aSt);
550 bIsConformState=GEOMAlgo_SurfaceTools::IsConformState(aSt, myState);
551 if (myShapeType==TopAbs_FACE) {
552 if (bIsConformState) {
556 else if (bIsConformState || aSt==TopAbs_ON) {
559 }// for (i=1; i<=aNb; ++i) next face
561 //=======================================================================
562 //function : ProcessSolids
564 //=======================================================================
565 void GEOMAlgo_FinderShapeOn2::ProcessSolids()
569 Standard_Boolean bIsConformState;
570 Standard_Integer i, aNbS, j, aNbF;
571 TopTools_IndexedMapOfShape aM, aMF;
574 TopExp::MapShapes(myShape, TopAbs_SOLID, aM);
576 for (i=1; i<=aNbS; ++i) {
577 GEOMAlgo_StateCollector aSC;
579 const TopoDS_Shape& aSd=aM(i);
581 TopExp::MapShapes(aSd, TopAbs_FACE, aMF);
583 for (j=1; j<=aNbF; ++j) {
584 const TopoDS_Shape& aF=aMF(j);
585 bIsConformState=myMSS.Contains(aF);
586 if (!bIsConformState) {
587 break;// face has non-conformed state
590 aSt=myMSS.FindFromKey(aF);
591 aSC.AppendState(aSt);
595 if (!bIsConformState) {
596 continue; // face has non-conformed state,skip solid
601 bIsConformState=GEOMAlgo_SurfaceTools::IsConformState(aSt, myState);
602 if (bIsConformState) {
608 //=======================================================================
609 //function : InnerPoints
611 //=======================================================================
612 void GEOMAlgo_FinderShapeOn2::InnerPoints(const TopoDS_Face& aF,
613 GEOMAlgo_ListOfPnt& aLP)
615 Standard_Integer j, j1, j2, k, n[4], aNbLinks, aNx, aNb, iCnt;//, aNbMax, *pIds;
616 TopLoc_Location aLoc;
617 Handle(Poly_Triangulation) aTRF;
618 TColStd_MapOfInteger aMBN;
619 GEOMAlgo_DataMapOfPassKeyInteger aMPKI;
620 GEOMAlgo_DataMapIteratorOfDataMapOfPassKeyInteger aIt;
627 aTRF=BRep_Tool::Triangulation(aF, aLoc);
629 if (!GEOMAlgo_FinderShapeOn::BuildTriangulation(aF)) {
630 myWarningStatus=20; // no triangulation found
633 aTRF=BRep_Tool::Triangulation(aF, aLoc);
636 const gp_Trsf& aTrsf=aLoc.Transformation();
637 const Poly_Array1OfTriangle& aTrs=aTRF->Triangles();
638 const TColgp_Array1OfPnt& aNodes=aTRF->Nodes();
640 // map link/nbtriangles
643 for (j=j1; j<=j2; ++j) {
644 const Poly_Triangle& aTr=aTrs(j);
645 aTr.Get(n[0], n[1], n[2]);
647 for (k=0; k<3; ++k) {
648 GEOMAlgo_PassKey aPK;
650 aPK.SetIds(n[k], n[k+1]);
651 if (aMPKI.IsBound(aPK)) {
652 Standard_Integer& iCntX=aMPKI.ChangeFind(aPK);
661 // boundary nodes aMBN
662 aNbLinks=aMPKI.Extent();
663 aIt.Initialize(aMPKI);
664 for (; aIt.More(); aIt.Next()) {
667 const GEOMAlgo_PassKey& aPK=aIt.Key();
668 aNx=(Standard_Integer)aPK.Id(1);
670 aNx=(Standard_Integer)aPK.Id(2);
676 // inner nodes=all_nodes - boundary_nodes
679 for (j=j1; j<=j2; ++j) {
680 if (!aMBN.Contains(j)) {
681 aP=aNodes(j).Transformed(aTrsf);
688 //modified by NIZNHY-PKV Mon Sep 24 08:42:32 2012f
689 if (!aNb && myNbPntsMin) { // A
690 Standard_Boolean bIsDone, bHasFirstPoint, bHasSecondPoint;
691 Standard_Integer i, aNb, aIx, /*iErr, */aNbDomains;
692 Standard_Real aUMin, aUMax, aVMin, aVMax, dU, aUx, aVx, aV1, aV2;
694 gp_Dir2d aD2D (0., 1.);
696 Handle(Geom2d_Line) aL2D;
697 Handle(Geom_Surface) aS;
701 aFF.Orientation (TopAbs_FORWARD);
703 Geom2dHatch_Hatcher& aHatcher=myContext->Hatcher(aFF);
705 aS=BRep_Tool::Surface(aFF);
706 BRepTools::UVBounds(aFF, aUMin, aUMax, aVMin, aVMax);
709 dU=(aUMax-aUMin)/aNb;
710 for (i=1; i<aNb; ++i) {
712 aP2D.SetCoord(aUx, 0.);
713 aL2D=new Geom2d_Line (aP2D, aD2D);
714 Geom2dAdaptor_Curve aHCur(aL2D);
716 aHatcher.ClrHatchings();
717 aIx=aHatcher.AddHatching(aHCur);
720 bIsDone=aHatcher.TrimDone(aIx);
726 aHatcher.ComputeDomains(aIx);
727 bIsDone=aHatcher.IsDone(aIx);
732 aNbDomains=aHatcher.NbDomains(aIx);
733 for (j=1; j<=aNbDomains; ++j) {
734 const HatchGen_Domain& aDomain=aHatcher.Domain (aIx, j) ;
736 bHasFirstPoint=aDomain.HasFirstPoint();
737 bHasSecondPoint=aDomain.HasSecondPoint();
738 if (!bHasFirstPoint || !bHasSecondPoint) {
742 aV1=aDomain.FirstPoint().Parameter();
743 aV2=aDomain.SecondPoint().Parameter();
744 aVx=IntTools_Tools::IntermediatePoint(aV1, aV2);
746 aS->D0(aUx, aVx, aPx);
750 }// for (i=1; i<aNb; ++i) {
751 }// if (!aNb && myNbPntsMin) {
753 //=======================================================================
754 //function : InnerPoints
756 //=======================================================================
757 void GEOMAlgo_FinderShapeOn2::InnerPoints(const TopoDS_Edge& aE,
758 GEOMAlgo_ListOfPnt& aLP)
762 Standard_Integer j, aNbNodes, aIndex, aNb;
763 Handle(Poly_PolygonOnTriangulation) aPTE;
764 Handle(Poly_Triangulation) aTRE;
765 TopLoc_Location aLoc;
769 BRep_Tool::PolygonOnTriangulation(aE, aPTE, aTRE, aLoc);
770 if (aTRE.IsNull() || aPTE.IsNull()) {
771 Handle(Poly_Polygon3D) aPE = BRep_Tool::Polygon3D(aE, aLoc);
773 if (!GEOMAlgo_FinderShapeOn::BuildTriangulation(aE)) {
774 myErrorStatus=20; // no triangulation found
777 aPE = BRep_Tool::Polygon3D(aE, aLoc);
779 const gp_Trsf& aTrsf=aLoc.Transformation();
780 const TColgp_Array1OfPnt& aNodes=aPE->Nodes();
782 aNbNodes=aPE->NbNodes();
783 Standard_Integer low = aNodes.Lower(), up = aNodes.Upper();
784 for (j=low+1; j<up; ++j) {
785 aP=aNodes(j).Transformed(aTrsf);
790 const gp_Trsf& aTrsf=aLoc.Transformation();
791 const TColgp_Array1OfPnt& aNodes=aTRE->Nodes();
793 aNbNodes=aPTE->NbNodes();
794 const TColStd_Array1OfInteger& aInds=aPTE->Nodes();
795 for (j=2; j<aNbNodes; ++j) {
797 aP=aNodes(aIndex).Transformed(aTrsf);
803 if (!aNb && myNbPntsMin) {
804 // try to fill it yourself
805 InnerPoints(aE, myNbPntsMin, aLP);
809 //=======================================================================
810 //function : InnerPoints
812 //=======================================================================
813 void GEOMAlgo_FinderShapeOn2::InnerPoints(const TopoDS_Edge& aE,
814 const Standard_Integer aNbPntsMin,
815 GEOMAlgo_ListOfPnt& aLP)
817 // try to fill it yourself
818 Standard_Boolean bInf1, bInf2;
819 Standard_Integer j, aNbT;
820 Standard_Real dT, aT, aT1, aT2;
822 Handle(Geom_Curve) aC3D;
824 aC3D=BRep_Tool::Curve(aE, aT1, aT2);
829 bInf1=Precision::IsNegativeInfinite(aT1);
830 bInf2=Precision::IsPositiveInfinite(aT2);
831 if (bInf1 || bInf2) {
837 for (j=1; j<=aNbPntsMin; ++j) {
849 // 12 -unallowed type of sub-shapes
850 // 13 -unallowed state
851 // 15 -unallowed surface type
852 // 20- no triangulation found
853 // 30- can not obtain the line from the link
854 // 40- point can not be classified
855 // 41- invalid data for classifier
856 // 42- can not compute hatching
860 if (!aNb && myNbPntsMin) {
861 // try to fill it yourself
862 Standard_Boolean bIsDone;
863 Standard_Integer aN1, aN2;
864 Handle(Geom_Surface) aS;
865 GeomAdaptor_Surface aGAS;
866 GeomAbs_SurfaceType aType;
868 aS=BRep_Tool::Surface(aF);
870 aType=aGAS.GetType();
871 if (aType==GeomAbs_Plane || aType==GeomAbs_Cylinder) {
873 aNbLinks=aMPKI.Extent();
874 aIt.Initialize(aMPKI);
875 for (; aIt.More(); aIt.Next()) {
878 // take the first having occured inner link
880 const GEOMAlgo_PassKey& aPK=aIt.Key();
882 aN1=(Standard_Integer)aPK.Id(1);
883 aN2=(Standard_Integer)aPK.Id(2);
885 aP1=aNodes(aN1).Transformed(aTrsf);
886 aP2=aNodes(aN2).Transformed(aTrsf);
888 if (aType==GeomAbs_Cylinder) {
891 aCyl=aGAS.Cylinder();
892 if (!GEOMAlgo_SurfaceTools::IsCoaxial(aP1, aP2, aCyl, myTolerance)) {
897 BRepLib_MakeEdge aBME(aP1, aP2);
898 bIsDone=aBME.IsDone();
900 myErrorStatus=30; //can not obtain the line fron the link
904 const TopoDS_Shape& aSx=aBME.Shape();
905 const TopoDS_Edge& aE=TopoDS::Edge(aSx);
907 InnerPoints(aE, myNbPntsMin, aLP);
910 }// for (; aIt.More(); aIt.Next())
911 }// if (aType==GeomAbs_Plane || aType==GeomAbs_Cylinder)
912 }// if (!aNb && myNbPntsMin) {