1 // Copyright (C) 2007-2013 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.
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>
32 #include <Precision.hxx>
33 #include <TColStd_Array1OfInteger.hxx>
34 #include <TColStd_MapOfInteger.hxx>
36 #include <gp_Trsf.hxx>
37 #include <gp_Cylinder.hxx>
40 #include <TColgp_Array1OfPnt.hxx>
42 #include <Poly_Array1OfTriangle.hxx>
43 #include <Poly_Triangle.hxx>
44 #include <Poly_PolygonOnTriangulation.hxx>
45 #include <Poly_Triangulation.hxx>
46 #include <Poly_Polygon3D.hxx>
48 #include <Geom_Curve.hxx>
49 #include <Geom_Surface.hxx>
50 #include <GeomAdaptor_Surface.hxx>
51 #include <GeomAbs_SurfaceType.hxx>
52 #include <GeomAdaptor_Curve.hxx>
53 #include <GeomAbs_CurveType.hxx>
55 #include <TopAbs_State.hxx>
57 #include <TopLoc_Location.hxx>
59 #include <TopoDS_Shape.hxx>
60 #include <TopoDS_Vertex.hxx>
61 #include <TopoDS_Face.hxx>
62 #include <TopoDS_Edge.hxx>
65 #include <TopExp_Explorer.hxx>
67 #include <TopTools_IndexedMapOfShape.hxx>
69 #include <BRep_Tool.hxx>
70 #include <BRepLib_MakeEdge.hxx>
72 #include <GEOMAlgo_ListIteratorOfListOfPnt.hxx>
73 #include <GEOMAlgo_SurfaceTools.hxx>
74 #include <GEOMAlgo_StateCollector.hxx>
75 #include <GEOMAlgo_FinderShapeOn.hxx>
77 #include <GEOMAlgo_PassKey.hxx>
78 #include <GEOMAlgo_DataMapOfPassKeyInteger.hxx>
79 #include <GEOMAlgo_DataMapIteratorOfDataMapOfPassKeyInteger.hxx>
81 #include <gp_Dir2d.hxx>
82 #include <gp_Pnt2d.hxx>
83 #include <Geom2d_Line.hxx>
84 #include <Geom2dAdaptor_Curve.hxx>
85 #include <Geom2dHatch_Hatcher.hxx>
86 #include <TColStd_ListOfInteger.hxx>
87 #include <TColStd_ListIteratorOfListOfInteger.hxx>
88 #include <HatchGen_Domain.hxx>
89 #include <Geom2dHatch_Hatcher.hxx>
90 #include <BOPInt_Context.hxx>
91 #include <BRepTools.hxx>
92 #include <IntTools_Tools.hxx>
94 //=======================================================================
97 //=======================================================================
98 GEOMAlgo_FinderShapeOn2::GEOMAlgo_FinderShapeOn2()
103 myShapeType=TopAbs_VERTEX;
104 myState=GEOMAlgo_ST_UNKNOWN;
108 //=======================================================================
111 //=======================================================================
112 GEOMAlgo_FinderShapeOn2::~GEOMAlgo_FinderShapeOn2()
115 //=======================================================================
118 //=======================================================================
119 void GEOMAlgo_FinderShapeOn2::SetClsf(const Handle(GEOMAlgo_Clsf)& aClsf)
123 //=======================================================================
126 //=======================================================================
127 const Handle(GEOMAlgo_Clsf)& GEOMAlgo_FinderShapeOn2::Clsf() const
131 //=======================================================================
132 //function : SetShapeType
134 //=======================================================================
135 void GEOMAlgo_FinderShapeOn2::SetShapeType(const TopAbs_ShapeEnum aType)
139 //=======================================================================
140 //function : ShapeType
142 //=======================================================================
143 TopAbs_ShapeEnum GEOMAlgo_FinderShapeOn2::ShapeType()const
147 //=======================================================================
148 //function : SetState
150 //=======================================================================
151 void GEOMAlgo_FinderShapeOn2::SetState(const GEOMAlgo_State aState)
155 //=======================================================================
158 //=======================================================================
159 GEOMAlgo_State GEOMAlgo_FinderShapeOn2::State() const
163 //=======================================================================
164 //function : SetNbPntsMin
166 //=======================================================================
167 void GEOMAlgo_FinderShapeOn2::SetNbPntsMin(const Standard_Integer aNb)
171 //=======================================================================
172 //function : NbPntsMin
174 //=======================================================================
175 Standard_Integer GEOMAlgo_FinderShapeOn2::NbPntsMin()const
179 //=======================================================================
180 //function : SetNbPntsMax
182 //=======================================================================
183 void GEOMAlgo_FinderShapeOn2::SetNbPntsMax(const Standard_Integer aNb)
187 //=======================================================================
188 //function : NbPntsMax
190 //=======================================================================
191 Standard_Integer GEOMAlgo_FinderShapeOn2::NbPntsMax()const
195 //=======================================================================
198 //=======================================================================
199 const GEOMAlgo_IndexedDataMapOfShapeState& GEOMAlgo_FinderShapeOn2::MSS() const
203 //=======================================================================
206 //=======================================================================
207 const TopTools_ListOfShape& GEOMAlgo_FinderShapeOn2::Shapes() const
209 Standard_Integer i, aNb;
210 TopTools_ListOfShape* pL;
212 pL=(TopTools_ListOfShape*) &myLS;
216 for (i=1; i<=aNb; ++i) {
217 const TopoDS_Shape& aS=myMSS.FindKey(i);
218 if (aS.ShapeType()==myShapeType) {
224 //=======================================================================
227 //=======================================================================
228 void GEOMAlgo_FinderShapeOn2::Perform()
240 // Initialize the context
241 GEOMAlgo_ShapeAlgo::Perform();
243 myClsf->SetTolerance(myTolerance);
250 if (myShapeType==TopAbs_VERTEX) {
259 if (myShapeType==TopAbs_EDGE) {
268 if (myShapeType==TopAbs_FACE) {
276 //=======================================================================
277 //function : CheckData
279 //=======================================================================
280 void GEOMAlgo_FinderShapeOn2::CheckData()
282 Standard_Integer iErr;
286 if(myClsf.IsNull()) {
287 myErrorStatus=10; // myClsf=NULL
292 iErr=myClsf->ErrorStatus();
294 myErrorStatus=41; // invalid data for classifier
298 if (myShape.IsNull()) {
299 myErrorStatus=11; // myShape=NULL
303 if (!(myShapeType==TopAbs_VERTEX ||
304 myShapeType==TopAbs_EDGE ||
305 myShapeType==TopAbs_FACE ||
306 myShapeType==TopAbs_SOLID)) {
307 myErrorStatus=12; // unallowed sub-shape type
311 if (myState==GEOMAlgo_ST_UNKNOWN ||
312 myState==GEOMAlgo_ST_INOUT) {
313 myErrorStatus=13; // unallowed state type
317 //=======================================================================
318 //function : ProcessVertices
320 //=======================================================================
321 void GEOMAlgo_FinderShapeOn2::ProcessVertices()
325 Standard_Boolean bIsConformState;
326 Standard_Integer i, aNb, iErr;
328 TopTools_IndexedMapOfShape aM;
331 TopExp::MapShapes(myShape, TopAbs_VERTEX, aM);
333 for (i=1; i<=aNb; ++i) {
334 const TopoDS_Vertex& aV=TopoDS::Vertex(aM(i));
335 aP=BRep_Tool::Pnt(aV);
339 iErr=myClsf->ErrorStatus();
341 myErrorStatus=40; // point can not be classified
346 bIsConformState=GEOMAlgo_SurfaceTools::IsConformState(aSt, myState);
348 if (myShapeType==TopAbs_VERTEX){
349 if (bIsConformState) {
353 else if (bIsConformState || aSt==TopAbs_ON) {
358 //=======================================================================
359 //function : ProcessEdges
361 //=======================================================================
362 void GEOMAlgo_FinderShapeOn2::ProcessEdges()
366 Standard_Boolean bIsConformState, bIsToBreak;
367 Standard_Integer i, aNb, iCnt, iErr;
369 TopTools_IndexedMapOfShape aM;
370 TopExp_Explorer aExp;
371 GEOMAlgo_ListIteratorOfListOfPnt aIt;
373 TopExp::MapShapes(myShape, TopAbs_EDGE, aM);
375 for (i=1; i<=aNb; ++i) {
376 GEOMAlgo_ListOfPnt aLP;
377 GEOMAlgo_StateCollector aSC;
379 const TopoDS_Edge& aE=TopoDS::Edge(aM(i));
381 aExp.Init(aE, TopAbs_VERTEX);
382 for (; aExp.More(); aExp.Next()) {
383 const TopoDS_Shape& aV=aExp.Current();
385 bIsConformState=myMSS.Contains(aV);
386 if (!bIsConformState) {
387 break;// vertex has non-conformed state
390 aSt=myMSS.FindFromKey(aV);
391 aSC.AppendState(aSt);
395 if (!bIsConformState) {
396 continue; // vertex has non-conformed state,skip edge
399 if (BRep_Tool::Degenerated(aE)) {
404 if (myState==GEOMAlgo_ST_ON) {
405 Standard_Boolean bCanBeON;
406 Standard_Real aT1, aT2;
407 Handle(Geom_Curve) aC;
409 aC=BRep_Tool::Curve(aE, aT1, aT2);
410 bCanBeON=myClsf->CanBeON(aC);
416 InnerPoints(aE, aLP);
421 bIsConformState=Standard_True;
423 for (iCnt=0; aIt.More(); aIt.Next(), ++iCnt) {
425 if (iCnt > myNbPntsMax) {
430 const gp_Pnt& aP=aIt.Value();
434 iErr=myClsf->ErrorStatus();
436 myErrorStatus=40; // point can not be classified
442 bIsToBreak=aSC.AppendState(aSt);
450 bIsConformState=GEOMAlgo_SurfaceTools::IsConformState(aSt, myState);
451 if (myShapeType==TopAbs_EDGE) {
452 if (bIsConformState) {
456 else if (bIsConformState || aSt==TopAbs_ON) {
459 } // for (i=1; i<=aNb; ++i) next edge
461 //=======================================================================
462 //function : ProcessFaces
464 //=======================================================================
465 void GEOMAlgo_FinderShapeOn2::ProcessFaces()
469 Standard_Boolean bIsConformState, bIsToBreak, bCanBeON;
470 Standard_Integer i, aNbF, iCnt, iErr;
472 TopTools_IndexedMapOfShape aM;
473 TopExp_Explorer aExp;
474 GEOMAlgo_ListIteratorOfListOfPnt aIt;
476 TopExp::MapShapes(myShape, TopAbs_FACE, aM);
478 for (i=1; i<=aNbF; ++i) {
479 GEOMAlgo_StateCollector aSC;
480 GEOMAlgo_ListOfPnt aLP;
482 const TopoDS_Face& aF=TopoDS::Face(aM(i));
484 if (myState==GEOMAlgo_ST_ON) {
485 Handle(Geom_Surface) aS;
487 aS=BRep_Tool::Surface(aF);
488 bCanBeON=myClsf->CanBeON(aS);
494 aExp.Init(aF, TopAbs_EDGE);
495 for (; aExp.More(); aExp.Next()) {
496 const TopoDS_Shape& aE=aExp.Current();
497 bIsConformState=myMSS.Contains(aE);
498 if (!bIsConformState) {
499 break;// edge has non-conformed state
502 aSt=myMSS.FindFromKey(aE);
503 aSC.AppendState(aSt);
507 if (!bIsConformState) {
508 continue; // edge has non-conformed state,skip face
511 InnerPoints(aF, aLP);
516 bIsConformState=Standard_True;
518 for (iCnt=0; aIt.More(); aIt.Next(), ++iCnt) {
520 if (iCnt > myNbPntsMax) {
525 const gp_Pnt& aP=aIt.Value();
529 iErr=myClsf->ErrorStatus();
531 myErrorStatus=40; // point can not be classified
537 bIsToBreak=aSC.AppendState(aSt);
545 bIsConformState=GEOMAlgo_SurfaceTools::IsConformState(aSt, myState);
546 if (myShapeType==TopAbs_FACE) {
547 if (bIsConformState) {
551 else if (bIsConformState || aSt==TopAbs_ON) {
554 }// for (i=1; i<=aNb; ++i) next face
556 //=======================================================================
557 //function : ProcessSolids
559 //=======================================================================
560 void GEOMAlgo_FinderShapeOn2::ProcessSolids()
564 Standard_Boolean bIsConformState;
565 Standard_Integer i, aNbS, j, aNbF;
566 TopTools_IndexedMapOfShape aM, aMF;
569 TopExp::MapShapes(myShape, TopAbs_SOLID, aM);
571 for (i=1; i<=aNbS; ++i) {
572 GEOMAlgo_StateCollector aSC;
574 const TopoDS_Shape& aSd=aM(i);
576 TopExp::MapShapes(aSd, TopAbs_FACE, aMF);
578 for (j=1; j<=aNbF; ++j) {
579 const TopoDS_Shape& aF=aMF(j);
580 bIsConformState=myMSS.Contains(aF);
581 if (!bIsConformState) {
582 break;// face has non-conformed state
585 aSt=myMSS.FindFromKey(aF);
586 aSC.AppendState(aSt);
590 if (!bIsConformState) {
591 continue; // face has non-conformed state,skip solid
596 bIsConformState=GEOMAlgo_SurfaceTools::IsConformState(aSt, myState);
597 if (bIsConformState) {
603 //=======================================================================
604 //function : InnerPoints
606 //=======================================================================
607 void GEOMAlgo_FinderShapeOn2::InnerPoints(const TopoDS_Face& aF,
608 GEOMAlgo_ListOfPnt& aLP)
610 Standard_Integer j, j1, j2, k, n[4], aNbLinks, aNx, aNb, iCnt;//, aNbMax, *pIds;
611 TopLoc_Location aLoc;
612 Handle(Poly_Triangulation) aTRF;
613 TColStd_MapOfInteger aMBN;
614 GEOMAlgo_DataMapOfPassKeyInteger aMPKI;
615 GEOMAlgo_DataMapIteratorOfDataMapOfPassKeyInteger aIt;
622 aTRF=BRep_Tool::Triangulation(aF, aLoc);
624 if (!GEOMAlgo_FinderShapeOn::BuildTriangulation(aF)) {
625 myWarningStatus=20; // no triangulation found
628 aTRF=BRep_Tool::Triangulation(aF, aLoc);
631 const gp_Trsf& aTrsf=aLoc.Transformation();
632 const Poly_Array1OfTriangle& aTrs=aTRF->Triangles();
633 const TColgp_Array1OfPnt& aNodes=aTRF->Nodes();
635 // map link/nbtriangles
638 for (j=j1; j<=j2; ++j) {
639 const Poly_Triangle& aTr=aTrs(j);
640 aTr.Get(n[0], n[1], n[2]);
642 for (k=0; k<3; ++k) {
643 GEOMAlgo_PassKey aPK;
645 aPK.SetIds(n[k], n[k+1]);
646 if (aMPKI.IsBound(aPK)) {
647 Standard_Integer& iCntX=aMPKI.ChangeFind(aPK);
656 // boundary nodes aMBN
657 aNbLinks=aMPKI.Extent();
658 aIt.Initialize(aMPKI);
659 for (; aIt.More(); aIt.Next()) {
662 const GEOMAlgo_PassKey& aPK=aIt.Key();
663 aNx=(Standard_Integer)aPK.Id(1);
665 aNx=(Standard_Integer)aPK.Id(2);
671 // inner nodes=all_nodes - boundary_nodes
674 for (j=j1; j<=j2; ++j) {
675 if (!aMBN.Contains(j)) {
676 aP=aNodes(j).Transformed(aTrsf);
683 //modified by NIZNHY-PKV Mon Sep 24 08:42:32 2012f
684 if (!aNb && myNbPntsMin) { // A
685 Standard_Boolean bIsDone, bHasFirstPoint, bHasSecondPoint;
686 Standard_Integer i, aNb, aIx, /*iErr, */aNbDomains;
687 Standard_Real aUMin, aUMax, aVMin, aVMax, dU, aUx, aVx, aV1, aV2;
689 gp_Dir2d aD2D (0., 1.);
691 Handle(Geom2d_Line) aL2D;
692 Handle(Geom_Surface) aS;
696 aFF.Orientation (TopAbs_FORWARD);
698 Geom2dHatch_Hatcher& aHatcher=myContext->Hatcher(aFF);
700 aS=BRep_Tool::Surface(aFF);
701 BRepTools::UVBounds(aFF, aUMin, aUMax, aVMin, aVMax);
704 dU=(aUMax-aUMin)/aNb;
705 for (i=1; i<aNb; ++i) {
707 aP2D.SetCoord(aUx, 0.);
708 aL2D=new Geom2d_Line (aP2D, aD2D);
709 Geom2dAdaptor_Curve aHCur(aL2D);
711 aHatcher.ClrHatchings();
712 aIx=aHatcher.AddHatching(aHCur);
715 bIsDone=aHatcher.TrimDone(aIx);
721 aHatcher.ComputeDomains(aIx);
722 bIsDone=aHatcher.IsDone(aIx);
727 aNbDomains=aHatcher.NbDomains(aIx);
728 for (j=1; j<=aNbDomains; ++j) {
729 const HatchGen_Domain& aDomain=aHatcher.Domain (aIx, j) ;
731 bHasFirstPoint=aDomain.HasFirstPoint();
732 bHasSecondPoint=aDomain.HasSecondPoint();
733 if (!bHasFirstPoint || !bHasSecondPoint) {
737 aV1=aDomain.FirstPoint().Parameter();
738 aV2=aDomain.SecondPoint().Parameter();
739 aVx=IntTools_Tools::IntermediatePoint(aV1, aV2);
741 aS->D0(aUx, aVx, aPx);
745 }// for (i=1; i<aNb; ++i) {
746 }// if (!aNb && myNbPntsMin) {
748 //=======================================================================
749 //function : InnerPoints
751 //=======================================================================
752 void GEOMAlgo_FinderShapeOn2::InnerPoints(const TopoDS_Edge& aE,
753 GEOMAlgo_ListOfPnt& aLP)
757 Standard_Integer j, aNbNodes, aIndex, aNb;
758 Handle(Poly_PolygonOnTriangulation) aPTE;
759 Handle(Poly_Triangulation) aTRE;
760 TopLoc_Location aLoc;
764 BRep_Tool::PolygonOnTriangulation(aE, aPTE, aTRE, aLoc);
765 if (aTRE.IsNull() || aPTE.IsNull()) {
766 Handle(Poly_Polygon3D) aPE = BRep_Tool::Polygon3D(aE, aLoc);
768 if (!GEOMAlgo_FinderShapeOn::BuildTriangulation(aE)) {
769 myErrorStatus=20; // no triangulation found
772 aPE = BRep_Tool::Polygon3D(aE, aLoc);
774 const gp_Trsf& aTrsf=aLoc.Transformation();
775 const TColgp_Array1OfPnt& aNodes=aPE->Nodes();
777 aNbNodes=aPE->NbNodes();
778 Standard_Integer low = aNodes.Lower(), up = aNodes.Upper();
779 for (j=low+1; j<up; ++j) {
780 aP=aNodes(j).Transformed(aTrsf);
785 const gp_Trsf& aTrsf=aLoc.Transformation();
786 const TColgp_Array1OfPnt& aNodes=aTRE->Nodes();
788 aNbNodes=aPTE->NbNodes();
789 const TColStd_Array1OfInteger& aInds=aPTE->Nodes();
790 for (j=2; j<aNbNodes; ++j) {
792 aP=aNodes(aIndex).Transformed(aTrsf);
798 if (!aNb && myNbPntsMin) {
799 // try to fill it yourself
800 InnerPoints(aE, myNbPntsMin, aLP);
804 //=======================================================================
805 //function : InnerPoints
807 //=======================================================================
808 void GEOMAlgo_FinderShapeOn2::InnerPoints(const TopoDS_Edge& aE,
809 const Standard_Integer aNbPntsMin,
810 GEOMAlgo_ListOfPnt& aLP)
812 // try to fill it yourself
813 Standard_Boolean bInf1, bInf2;
814 Standard_Integer j, aNbT;
815 Standard_Real dT, aT, aT1, aT2;
817 Handle(Geom_Curve) aC3D;
819 aC3D=BRep_Tool::Curve(aE, aT1, aT2);
824 bInf1=Precision::IsNegativeInfinite(aT1);
825 bInf2=Precision::IsPositiveInfinite(aT2);
826 if (bInf1 || bInf2) {
832 for (j=1; j<=aNbPntsMin; ++j) {
844 // 12 -unallowed type of sub-shapes
845 // 13 -unallowed state
846 // 15 -unallowed surface type
847 // 20- no triangulation found
848 // 30- can not obtain the line from the link
849 // 40- point can not be classified
850 // 41- invalid data for classifier
851 // 42- can not compute hatching
855 if (!aNb && myNbPntsMin) {
856 // try to fill it yourself
857 Standard_Boolean bIsDone;
858 Standard_Integer aN1, aN2;
859 Handle(Geom_Surface) aS;
860 GeomAdaptor_Surface aGAS;
861 GeomAbs_SurfaceType aType;
863 aS=BRep_Tool::Surface(aF);
865 aType=aGAS.GetType();
866 if (aType==GeomAbs_Plane || aType==GeomAbs_Cylinder) {
868 aNbLinks=aMPKI.Extent();
869 aIt.Initialize(aMPKI);
870 for (; aIt.More(); aIt.Next()) {
873 // take the first having occured inner link
875 const GEOMAlgo_PassKey& aPK=aIt.Key();
877 aN1=(Standard_Integer)aPK.Id(1);
878 aN2=(Standard_Integer)aPK.Id(2);
880 aP1=aNodes(aN1).Transformed(aTrsf);
881 aP2=aNodes(aN2).Transformed(aTrsf);
883 if (aType==GeomAbs_Cylinder) {
884 Standard_Real aTolSM;
887 aTolSM=1.523e-6;//~1.-cos(0.1 deg)
888 aCyl=aGAS.Cylinder();
889 if (!GEOMAlgo_SurfaceTools::IsCoaxial(aP1, aP2, aCyl, aTolSM)) {
894 BRepLib_MakeEdge aBME(aP1, aP2);
895 bIsDone=aBME.IsDone();
897 myErrorStatus=30; //can not obtain the line fron the link
901 const TopoDS_Shape& aSx=aBME.Shape();
902 const TopoDS_Edge& aE=TopoDS::Edge(aSx);
904 InnerPoints(aE, myNbPntsMin, aLP);
907 }// for (; aIt.More(); aIt.Next())
908 }// if (aType==GeomAbs_Plane || aType==GeomAbs_Cylinder)
909 }// if (!aNb && myNbPntsMin) {