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>
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 #include <IntTools_Context.hxx>
92 #include <BRepTools.hxx>
93 #include <IntTools_Tools.hxx>
95 //=======================================================================
96 //function : GEOMAlgo_FinderShapeOn1
98 //=======================================================================
99 GEOMAlgo_FinderShapeOn2::GEOMAlgo_FinderShapeOn2()
104 myShapeType=TopAbs_VERTEX;
105 myState=GEOMAlgo_ST_UNKNOWN;
109 //=======================================================================
112 //=======================================================================
113 GEOMAlgo_FinderShapeOn2::~GEOMAlgo_FinderShapeOn2()
116 //=======================================================================
119 //=======================================================================
120 void GEOMAlgo_FinderShapeOn2::SetClsf(const Handle(GEOMAlgo_Clsf)& aClsf)
124 //=======================================================================
127 //=======================================================================
128 const Handle(GEOMAlgo_Clsf)& GEOMAlgo_FinderShapeOn2::Clsf() const
132 //=======================================================================
133 //function : SetShapeType
135 //=======================================================================
136 void GEOMAlgo_FinderShapeOn2::SetShapeType(const TopAbs_ShapeEnum aType)
140 //=======================================================================
141 //function : ShapeType
143 //=======================================================================
144 TopAbs_ShapeEnum GEOMAlgo_FinderShapeOn2::ShapeType()const
148 //=======================================================================
149 //function : SetState
151 //=======================================================================
152 void GEOMAlgo_FinderShapeOn2::SetState(const GEOMAlgo_State aState)
156 //=======================================================================
159 //=======================================================================
160 GEOMAlgo_State GEOMAlgo_FinderShapeOn2::State() const
164 //=======================================================================
165 //function : SetNbPntsMin
167 //=======================================================================
168 void GEOMAlgo_FinderShapeOn2::SetNbPntsMin(const Standard_Integer aNb)
172 //=======================================================================
173 //function : NbPntsMin
175 //=======================================================================
176 Standard_Integer GEOMAlgo_FinderShapeOn2::NbPntsMin()const
180 //=======================================================================
181 //function : SetNbPntsMax
183 //=======================================================================
184 void GEOMAlgo_FinderShapeOn2::SetNbPntsMax(const Standard_Integer aNb)
188 //=======================================================================
189 //function : NbPntsMax
191 //=======================================================================
192 Standard_Integer GEOMAlgo_FinderShapeOn2::NbPntsMax()const
196 //=======================================================================
199 //=======================================================================
200 const GEOMAlgo_IndexedDataMapOfShapeState& GEOMAlgo_FinderShapeOn2::MSS() const
204 //=======================================================================
207 //=======================================================================
208 const TopTools_ListOfShape& GEOMAlgo_FinderShapeOn2::Shapes() const
210 Standard_Integer i, aNb;
211 TopTools_ListOfShape* pL;
213 pL=(TopTools_ListOfShape*) &myLS;
217 for (i=1; i<=aNb; ++i) {
218 const TopoDS_Shape& aS=myMSS.FindKey(i);
219 if (aS.ShapeType()==myShapeType) {
225 //=======================================================================
228 //=======================================================================
229 void GEOMAlgo_FinderShapeOn2::Perform()
241 // Initialize the context
242 GEOMAlgo_ShapeAlgo::Perform();
244 myClsf->SetTolerance(myTolerance);
251 if (myShapeType==TopAbs_VERTEX) {
260 if (myShapeType==TopAbs_EDGE) {
269 if (myShapeType==TopAbs_FACE) {
277 //=======================================================================
278 //function : CheckData
280 //=======================================================================
281 void GEOMAlgo_FinderShapeOn2::CheckData()
283 Standard_Integer iErr;
287 if(myClsf.IsNull()) {
288 myErrorStatus=10; // myClsf=NULL
293 iErr=myClsf->ErrorStatus();
295 myErrorStatus=41; // invalid data for classifier
299 if (myShape.IsNull()) {
300 myErrorStatus=11; // myShape=NULL
304 if (!(myShapeType==TopAbs_VERTEX ||
305 myShapeType==TopAbs_EDGE ||
306 myShapeType==TopAbs_FACE ||
307 myShapeType==TopAbs_SOLID)) {
308 myErrorStatus=12; // unallowed sub-shape type
312 if (myState==GEOMAlgo_ST_UNKNOWN ||
313 myState==GEOMAlgo_ST_INOUT) {
314 myErrorStatus=13; // unallowed state type
318 //=======================================================================
319 //function : ProcessVertices
321 //=======================================================================
322 void GEOMAlgo_FinderShapeOn2::ProcessVertices()
326 Standard_Boolean bIsConformState;
327 Standard_Integer i, aNb, iErr;
329 TopTools_IndexedMapOfShape aM;
332 TopExp::MapShapes(myShape, TopAbs_VERTEX, aM);
334 for (i=1; i<=aNb; ++i) {
335 const TopoDS_Vertex& aV=TopoDS::Vertex(aM(i));
336 aP=BRep_Tool::Pnt(aV);
340 iErr=myClsf->ErrorStatus();
342 myErrorStatus=40; // point can not be classified
347 bIsConformState=GEOMAlgo_SurfaceTools::IsConformState(aSt, myState);
349 if (myShapeType==TopAbs_VERTEX){
350 if (bIsConformState) {
354 else if (bIsConformState || aSt==TopAbs_ON) {
359 //=======================================================================
360 //function : ProcessEdges
362 //=======================================================================
363 void GEOMAlgo_FinderShapeOn2::ProcessEdges()
367 Standard_Boolean bIsConformState, bIsToBreak;
368 Standard_Integer i, aNb, iCnt, iErr;
370 TopTools_IndexedMapOfShape aM;
371 TopExp_Explorer aExp;
372 GEOMAlgo_ListIteratorOfListOfPnt aIt;
374 TopExp::MapShapes(myShape, TopAbs_EDGE, aM);
376 for (i=1; i<=aNb; ++i) {
377 GEOMAlgo_ListOfPnt aLP;
378 GEOMAlgo_StateCollector aSC;
380 const TopoDS_Edge& aE=TopoDS::Edge(aM(i));
382 aExp.Init(aE, TopAbs_VERTEX);
383 for (; aExp.More(); aExp.Next()) {
384 const TopoDS_Shape& aV=aExp.Current();
386 bIsConformState=myMSS.Contains(aV);
387 if (!bIsConformState) {
388 break;// vertex has non-conformed state
391 aSt=myMSS.FindFromKey(aV);
392 aSC.AppendState(aSt);
396 if (!bIsConformState) {
397 continue; // vertex has non-conformed state,skip edge
400 if (BRep_Tool::Degenerated(aE)) {
405 if (myState==GEOMAlgo_ST_ON) {
406 Standard_Boolean bCanBeON;
407 Standard_Real aT1, aT2;
408 Handle(Geom_Curve) aC;
410 aC=BRep_Tool::Curve(aE, aT1, aT2);
411 bCanBeON=myClsf->CanBeON(aC);
417 InnerPoints(aE, aLP);
422 bIsConformState=Standard_True;
424 for (iCnt=0; aIt.More(); aIt.Next(), ++iCnt) {
426 if (iCnt > myNbPntsMax) {
431 const gp_Pnt& aP=aIt.Value();
435 iErr=myClsf->ErrorStatus();
437 myErrorStatus=40; // point can not be classified
443 bIsToBreak=aSC.AppendState(aSt);
451 bIsConformState=GEOMAlgo_SurfaceTools::IsConformState(aSt, myState);
452 if (myShapeType==TopAbs_EDGE) {
453 if (bIsConformState) {
457 else if (bIsConformState || aSt==TopAbs_ON) {
460 } // for (i=1; i<=aNb; ++i) next edge
462 //=======================================================================
463 //function : ProcessFaces
465 //=======================================================================
466 void GEOMAlgo_FinderShapeOn2::ProcessFaces()
470 Standard_Boolean bIsConformState, bIsToBreak, bCanBeON;
471 Standard_Integer i, aNbF, iCnt, iErr;
473 TopTools_IndexedMapOfShape aM;
474 TopExp_Explorer aExp;
475 GEOMAlgo_ListIteratorOfListOfPnt aIt;
477 TopExp::MapShapes(myShape, TopAbs_FACE, aM);
479 for (i=1; i<=aNbF; ++i) {
480 GEOMAlgo_StateCollector aSC;
481 GEOMAlgo_ListOfPnt aLP;
483 const TopoDS_Face& aF=TopoDS::Face(aM(i));
485 if (myState==GEOMAlgo_ST_ON) {
486 Handle(Geom_Surface) aS;
488 aS=BRep_Tool::Surface(aF);
489 bCanBeON=myClsf->CanBeON(aS);
495 aExp.Init(aF, TopAbs_EDGE);
496 for (; aExp.More(); aExp.Next()) {
497 const TopoDS_Shape& aE=aExp.Current();
498 bIsConformState=myMSS.Contains(aE);
499 if (!bIsConformState) {
500 break;// edge has non-conformed state
503 aSt=myMSS.FindFromKey(aE);
504 aSC.AppendState(aSt);
508 if (!bIsConformState) {
509 continue; // edge has non-conformed state,skip face
512 InnerPoints(aF, aLP);
517 bIsConformState=Standard_True;
519 for (iCnt=0; aIt.More(); aIt.Next(), ++iCnt) {
521 if (iCnt > myNbPntsMax) {
526 const gp_Pnt& aP=aIt.Value();
530 iErr=myClsf->ErrorStatus();
532 myErrorStatus=40; // point can not be classified
538 bIsToBreak=aSC.AppendState(aSt);
546 bIsConformState=GEOMAlgo_SurfaceTools::IsConformState(aSt, myState);
547 if (myShapeType==TopAbs_FACE) {
548 if (bIsConformState) {
552 else if (bIsConformState || aSt==TopAbs_ON) {
555 }// for (i=1; i<=aNb; ++i) next face
557 //=======================================================================
558 //function : ProcessSolids
560 //=======================================================================
561 void GEOMAlgo_FinderShapeOn2::ProcessSolids()
565 Standard_Boolean bIsConformState;
566 Standard_Integer i, aNbS, j, aNbF;
567 TopTools_IndexedMapOfShape aM, aMF;
570 TopExp::MapShapes(myShape, TopAbs_SOLID, aM);
572 for (i=1; i<=aNbS; ++i) {
573 GEOMAlgo_StateCollector aSC;
575 const TopoDS_Shape& aSd=aM(i);
577 TopExp::MapShapes(aSd, TopAbs_FACE, aMF);
579 for (j=1; j<=aNbF; ++j) {
580 const TopoDS_Shape& aF=aMF(j);
581 bIsConformState=myMSS.Contains(aF);
582 if (!bIsConformState) {
583 break;// face has non-conformed state
586 aSt=myMSS.FindFromKey(aF);
587 aSC.AppendState(aSt);
591 if (!bIsConformState) {
592 continue; // face has non-conformed state,skip solid
597 bIsConformState=GEOMAlgo_SurfaceTools::IsConformState(aSt, myState);
598 if (bIsConformState) {
604 //=======================================================================
605 //function : InnerPoints
607 //=======================================================================
608 void GEOMAlgo_FinderShapeOn2::InnerPoints(const TopoDS_Face& aF,
609 GEOMAlgo_ListOfPnt& aLP)
611 Standard_Integer j, j1, j2, k, n[4], aNbLinks, aNx, aNb, iCnt;//, aNbMax, *pIds;
612 TopLoc_Location aLoc;
613 Handle(Poly_Triangulation) aTRF;
614 TColStd_MapOfInteger aMBN;
615 GEOMAlgo_DataMapOfPassKeyInteger aMPKI;
616 GEOMAlgo_DataMapIteratorOfDataMapOfPassKeyInteger aIt;
623 aTRF=BRep_Tool::Triangulation(aF, aLoc);
625 if (!GEOMAlgo_FinderShapeOn::BuildTriangulation(aF)) {
626 myWarningStatus=20; // no triangulation found
629 aTRF=BRep_Tool::Triangulation(aF, aLoc);
632 const gp_Trsf& aTrsf=aLoc.Transformation();
633 const Poly_Array1OfTriangle& aTrs=aTRF->Triangles();
634 const TColgp_Array1OfPnt& aNodes=aTRF->Nodes();
636 // map link/nbtriangles
639 for (j=j1; j<=j2; ++j) {
640 const Poly_Triangle& aTr=aTrs(j);
641 aTr.Get(n[0], n[1], n[2]);
643 for (k=0; k<3; ++k) {
644 GEOMAlgo_PassKey aPK;
646 aPK.SetIds(n[k], n[k+1]);
647 if (aMPKI.IsBound(aPK)) {
648 Standard_Integer& iCntX=aMPKI.ChangeFind(aPK);
657 // boundary nodes aMBN
658 aNbLinks=aMPKI.Extent();
659 aIt.Initialize(aMPKI);
660 for (; aIt.More(); aIt.Next()) {
663 const GEOMAlgo_PassKey& aPK=aIt.Key();
664 aNx=(Standard_Integer)aPK.Id(1);
666 aNx=(Standard_Integer)aPK.Id(2);
672 // inner nodes=all_nodes - boundary_nodes
675 for (j=j1; j<=j2; ++j) {
676 if (!aMBN.Contains(j)) {
677 aP=aNodes(j).Transformed(aTrsf);
684 //modified by NIZNHY-PKV Mon Sep 24 08:42:32 2012f
685 if (!aNb && myNbPntsMin) { // A
686 Standard_Boolean bIsDone, bHasFirstPoint, bHasSecondPoint;
687 Standard_Integer i, aNb, aIx, iErr, aNbDomains;
688 Standard_Real aUMin, aUMax, aVMin, aVMax, dU, aUx, aVx, aV1, aV2;
690 gp_Dir2d aD2D (0., 1.);
692 Handle(Geom2d_Line) aL2D;
693 Handle(Geom_Surface) aS;
697 aFF.Orientation (TopAbs_FORWARD);
699 Geom2dHatch_Hatcher& aHatcher=myContext->Hatcher(aFF);
701 aS=BRep_Tool::Surface(aFF);
702 BRepTools::UVBounds(aFF, aUMin, aUMax, aVMin, aVMax);
705 dU=(aUMax-aUMin)/aNb;
706 for (i=1; i<aNb; ++i) {
708 aP2D.SetCoord(aUx, 0.);
709 aL2D=new Geom2d_Line (aP2D, aD2D);
710 Geom2dAdaptor_Curve aHCur(aL2D);
712 aHatcher.ClrHatchings();
713 aIx=aHatcher.AddHatching(aHCur);
716 bIsDone=aHatcher.TrimDone(aIx);
722 aHatcher.ComputeDomains(aIx);
723 bIsDone=aHatcher.IsDone(aIx);
728 aNbDomains=aHatcher.NbDomains(aIx);
729 for (j=1; j<=aNbDomains; ++j) {
730 const HatchGen_Domain& aDomain=aHatcher.Domain (aIx, j) ;
732 bHasFirstPoint=aDomain.HasFirstPoint();
733 bHasSecondPoint=aDomain.HasSecondPoint();
734 if (!bHasFirstPoint || !bHasSecondPoint) {
738 aV1=aDomain.FirstPoint().Parameter();
739 aV2=aDomain.SecondPoint().Parameter();
740 aVx=IntTools_Tools::IntermediatePoint(aV1, aV2);
742 aS->D0(aUx, aVx, aPx);
746 }// for (i=1; i<aNb; ++i) {
747 }// if (!aNb && myNbPntsMin) {
749 //=======================================================================
750 //function : InnerPoints
752 //=======================================================================
753 void GEOMAlgo_FinderShapeOn2::InnerPoints(const TopoDS_Edge& aE,
754 GEOMAlgo_ListOfPnt& aLP)
758 Standard_Integer j, aNbNodes, aIndex, aNb;
759 Handle(Poly_PolygonOnTriangulation) aPTE;
760 Handle(Poly_Triangulation) aTRE;
761 TopLoc_Location aLoc;
765 BRep_Tool::PolygonOnTriangulation(aE, aPTE, aTRE, aLoc);
766 if (aTRE.IsNull() || aPTE.IsNull()) {
767 Handle(Poly_Polygon3D) aPE = BRep_Tool::Polygon3D(aE, aLoc);
769 if (!GEOMAlgo_FinderShapeOn::BuildTriangulation(aE)) {
770 myErrorStatus=20; // no triangulation found
773 aPE = BRep_Tool::Polygon3D(aE, aLoc);
775 const gp_Trsf& aTrsf=aLoc.Transformation();
776 const TColgp_Array1OfPnt& aNodes=aPE->Nodes();
778 aNbNodes=aPE->NbNodes();
779 Standard_Integer low = aNodes.Lower(), up = aNodes.Upper();
780 for (j=low+1; j<up; ++j) {
781 aP=aNodes(j).Transformed(aTrsf);
786 const gp_Trsf& aTrsf=aLoc.Transformation();
787 const TColgp_Array1OfPnt& aNodes=aTRE->Nodes();
789 aNbNodes=aPTE->NbNodes();
790 const TColStd_Array1OfInteger& aInds=aPTE->Nodes();
791 for (j=2; j<aNbNodes; ++j) {
793 aP=aNodes(aIndex).Transformed(aTrsf);
799 if (!aNb && myNbPntsMin) {
800 // try to fill it yourself
801 InnerPoints(aE, myNbPntsMin, aLP);
805 //=======================================================================
806 //function : InnerPoints
808 //=======================================================================
809 void GEOMAlgo_FinderShapeOn2::InnerPoints(const TopoDS_Edge& aE,
810 const Standard_Integer aNbPntsMin,
811 GEOMAlgo_ListOfPnt& aLP)
813 // try to fill it yourself
814 Standard_Boolean bInf1, bInf2;
815 Standard_Integer j, aNbT;
816 Standard_Real dT, aT, aT1, aT2;
818 Handle(Geom_Curve) aC3D;
820 aC3D=BRep_Tool::Curve(aE, aT1, aT2);
825 bInf1=Precision::IsNegativeInfinite(aT1);
826 bInf2=Precision::IsPositiveInfinite(aT2);
827 if (bInf1 || bInf2) {
833 for (j=1; j<=aNbPntsMin; ++j) {
845 // 12 -unallowed type of sub-shapes
846 // 13 -unallowed state
847 // 15 -unallowed surface type
848 // 20- no triangulation found
849 // 30- can not obtain the line from the link
850 // 40- point can not be classified
851 // 41- invalid data for classifier
852 // 42- can not compute hatching
856 if (!aNb && myNbPntsMin) {
857 // try to fill it yourself
858 Standard_Boolean bIsDone;
859 Standard_Integer aN1, aN2;
860 Handle(Geom_Surface) aS;
861 GeomAdaptor_Surface aGAS;
862 GeomAbs_SurfaceType aType;
864 aS=BRep_Tool::Surface(aF);
866 aType=aGAS.GetType();
867 if (aType==GeomAbs_Plane || aType==GeomAbs_Cylinder) {
869 aNbLinks=aMPKI.Extent();
870 aIt.Initialize(aMPKI);
871 for (; aIt.More(); aIt.Next()) {
874 // take the first having occured inner link
876 const GEOMAlgo_PassKey& aPK=aIt.Key();
878 aN1=(Standard_Integer)aPK.Id(1);
879 aN2=(Standard_Integer)aPK.Id(2);
881 aP1=aNodes(aN1).Transformed(aTrsf);
882 aP2=aNodes(aN2).Transformed(aTrsf);
884 if (aType==GeomAbs_Cylinder) {
885 Standard_Real aTolSM;
888 aTolSM=1.523e-6;//~1.-cos(0.1 deg)
889 aCyl=aGAS.Cylinder();
890 if (!GEOMAlgo_SurfaceTools::IsCoaxial(aP1, aP2, aCyl, aTolSM)) {
895 BRepLib_MakeEdge aBME(aP1, aP2);
896 bIsDone=aBME.IsDone();
898 myErrorStatus=30; //can not obtain the line fron the link
902 const TopoDS_Shape& aSx=aBME.Shape();
903 const TopoDS_Edge& aE=TopoDS::Edge(aSx);
905 InnerPoints(aE, myNbPntsMin, aLP);
908 }// for (; aIt.More(); aIt.Next())
909 }// if (aType==GeomAbs_Plane || aType==GeomAbs_Cylinder)
910 }// if (!aNb && myNbPntsMin) {