1 // Copyright (C) 2007-2016 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>
29 #include <GEOMAlgo_DataMapIteratorOfDataMapOfPassKeyInteger.hxx>
30 #include <GEOMAlgo_DataMapOfPassKeyInteger.hxx>
31 #include <GEOMAlgo_ListIteratorOfListOfPnt.hxx>
32 #include <GEOMAlgo_PassKey.hxx>
33 #include <GEOMAlgo_StateCollector.hxx>
34 #include <GEOMAlgo_SurfaceTools.hxx>
36 #include <Bnd_Box.hxx>
37 #include <BRep_Tool.hxx>
38 #include <BRepBndLib.hxx>
39 #include <BRepMesh_IncrementalMesh.hxx>
40 #include <BRepTools.hxx>
41 #include <Geom_Curve.hxx>
42 #include <Geom_Surface.hxx>
43 #include <Geom2d_Line.hxx>
44 #include <Geom2dAdaptor_Curve.hxx>
45 #include <Geom2dHatch_Hatcher.hxx>
46 #include <gp_Dir2d.hxx>
47 #include <gp_Pnt2d.hxx>
49 #include <gp_Trsf.hxx>
50 #include <HatchGen_Domain.hxx>
51 #include <IntTools_Tools.hxx>
52 #include <Poly_Array1OfTriangle.hxx>
53 #include <Poly_Polygon3D.hxx>
54 #include <Poly_PolygonOnTriangulation.hxx>
55 #include <Poly_Triangle.hxx>
56 #include <Poly_Triangulation.hxx>
57 #include <Precision.hxx>
58 #include <TColgp_Array1OfPnt.hxx>
59 #include <TColStd_Array1OfInteger.hxx>
60 #include <TColStd_MapOfInteger.hxx>
61 #include <TopAbs_State.hxx>
63 #include <TopExp_Explorer.hxx>
64 #include <TopLoc_Location.hxx>
66 #include <TopoDS_Edge.hxx>
67 #include <TopoDS_Face.hxx>
68 #include <TopoDS_Shape.hxx>
69 #include <TopoDS_Vertex.hxx>
70 #include <TopTools_IndexedMapOfShape.hxx>
72 #if OCC_VERSION_LARGE > 0x06070100
73 #include <IntTools_Context.hxx>
75 #include <BOPInt_Context.hxx>
78 //=======================================================================
81 //=======================================================================
82 GEOMAlgo_FinderShapeOn2::GEOMAlgo_FinderShapeOn2()
87 myShapeType=TopAbs_VERTEX;
88 myState=GEOMAlgo_ST_UNKNOWN;
92 //=======================================================================
95 //=======================================================================
96 GEOMAlgo_FinderShapeOn2::~GEOMAlgo_FinderShapeOn2()
99 //=======================================================================
102 //=======================================================================
103 void GEOMAlgo_FinderShapeOn2::SetClsf(const Handle(GEOMAlgo_Clsf)& aClsf)
107 //=======================================================================
110 //=======================================================================
111 const Handle(GEOMAlgo_Clsf)& GEOMAlgo_FinderShapeOn2::Clsf() const
115 //=======================================================================
116 //function : SetShapeType
118 //=======================================================================
119 void GEOMAlgo_FinderShapeOn2::SetShapeType(const TopAbs_ShapeEnum aType)
123 //=======================================================================
124 //function : ShapeType
126 //=======================================================================
127 TopAbs_ShapeEnum GEOMAlgo_FinderShapeOn2::ShapeType()const
131 //=======================================================================
132 //function : SetState
134 //=======================================================================
135 void GEOMAlgo_FinderShapeOn2::SetState(const GEOMAlgo_State aState)
139 //=======================================================================
142 //=======================================================================
143 GEOMAlgo_State GEOMAlgo_FinderShapeOn2::State() const
147 //=======================================================================
148 //function : SetNbPntsMin
150 //=======================================================================
151 void GEOMAlgo_FinderShapeOn2::SetNbPntsMin(const Standard_Integer aNb)
155 //=======================================================================
156 //function : NbPntsMin
158 //=======================================================================
159 Standard_Integer GEOMAlgo_FinderShapeOn2::NbPntsMin()const
163 //=======================================================================
164 //function : SetNbPntsMax
166 //=======================================================================
167 void GEOMAlgo_FinderShapeOn2::SetNbPntsMax(const Standard_Integer aNb)
171 //=======================================================================
172 //function : NbPntsMax
174 //=======================================================================
175 Standard_Integer GEOMAlgo_FinderShapeOn2::NbPntsMax()const
179 //=======================================================================
182 //=======================================================================
183 const GEOMAlgo_IndexedDataMapOfShapeState& GEOMAlgo_FinderShapeOn2::MSS() const
187 //=======================================================================
190 //=======================================================================
191 const TopTools_ListOfShape& GEOMAlgo_FinderShapeOn2::Shapes() const
193 Standard_Integer i, aNb;
194 TopTools_ListOfShape* pL;
196 pL=(TopTools_ListOfShape*) &myLS;
200 for (i=1; i<=aNb; ++i) {
201 const TopoDS_Shape& aS=myMSS.FindKey(i);
202 if (aS.ShapeType()==myShapeType) {
208 //=======================================================================
211 //=======================================================================
212 void GEOMAlgo_FinderShapeOn2::Perform()
224 // Initialize the context
225 GEOMAlgo_ShapeAlgo::Perform();
227 myClsf->SetTolerance(myTolerance);
234 if (myShapeType==TopAbs_VERTEX) {
243 if (myShapeType==TopAbs_EDGE) {
252 if (myShapeType==TopAbs_FACE) {
260 //=======================================================================
261 //function : CheckData
263 //=======================================================================
264 void GEOMAlgo_FinderShapeOn2::CheckData()
266 Standard_Integer iErr;
270 if(myClsf.IsNull()) {
271 myErrorStatus=10; // myClsf=NULL
276 iErr=myClsf->ErrorStatus();
278 myErrorStatus=41; // invalid data for classifier
282 if (myShape.IsNull()) {
283 myErrorStatus=11; // myShape=NULL
287 if (!(myShapeType==TopAbs_VERTEX ||
288 myShapeType==TopAbs_EDGE ||
289 myShapeType==TopAbs_FACE ||
290 myShapeType==TopAbs_SOLID)) {
291 myErrorStatus=12; // unallowed sub-shape type
295 if (myState==GEOMAlgo_ST_UNKNOWN ||
296 myState==GEOMAlgo_ST_INOUT) {
297 myErrorStatus=13; // unallowed state type
301 //=======================================================================
302 //function : ProcessVertices
304 //=======================================================================
305 void GEOMAlgo_FinderShapeOn2::ProcessVertices()
309 Standard_Boolean bIsConformState;
310 Standard_Integer i, aNb, iErr;
312 TopTools_IndexedMapOfShape aM;
315 TopExp::MapShapes(myShape, TopAbs_VERTEX, aM);
317 for (i=1; i<=aNb; ++i) {
318 const TopoDS_Vertex& aV=TopoDS::Vertex(aM(i));
319 aP=BRep_Tool::Pnt(aV);
323 iErr=myClsf->ErrorStatus();
325 myErrorStatus=40; // point can not be classified
330 bIsConformState=GEOMAlgo_SurfaceTools::IsConformState(aSt, myState);
332 if (myShapeType==TopAbs_VERTEX){
333 if (bIsConformState) {
337 else if (bIsConformState || aSt==TopAbs_ON) {
342 //=======================================================================
343 //function : ProcessEdges
345 //=======================================================================
346 void GEOMAlgo_FinderShapeOn2::ProcessEdges()
350 Standard_Boolean bIsConformState, bIsToBreak;
351 Standard_Integer i, aNb, iCnt, iErr;
353 TopTools_IndexedMapOfShape aM;
354 TopExp_Explorer aExp;
355 GEOMAlgo_ListIteratorOfListOfPnt aIt;
357 TopExp::MapShapes(myShape, TopAbs_EDGE, aM);
359 for (i=1; i<=aNb; ++i) {
360 GEOMAlgo_ListOfPnt aLP;
361 GEOMAlgo_StateCollector aSC;
363 const TopoDS_Edge& aE=TopoDS::Edge(aM(i));
365 bIsConformState=Standard_False;
367 aExp.Init(aE, TopAbs_VERTEX);
368 for (; aExp.More(); aExp.Next()) {
369 const TopoDS_Shape& aV=aExp.Current();
371 bIsConformState=myMSS.Contains(aV);
372 if (!bIsConformState) {
373 break;// vertex has non-conformed state
376 aSt=myMSS.FindFromKey(aV);
377 aSC.AppendState(aSt);
381 if (!bIsConformState) {
382 continue; // vertex has non-conformed state,skip edge
385 if (BRep_Tool::Degenerated(aE)) {
390 if (myState==GEOMAlgo_ST_ON) {
391 Standard_Boolean bCanBeON;
392 Standard_Real aT1, aT2;
393 Handle(Geom_Curve) aC;
395 aC=BRep_Tool::Curve(aE, aT1, aT2);
396 bCanBeON=myClsf->CanBeON(aC);
402 InnerPoints(aE, aLP);
407 bIsConformState=Standard_True;
409 for (iCnt=0; aIt.More(); aIt.Next(), ++iCnt) {
411 if (iCnt > myNbPntsMax) {
416 const gp_Pnt& aP=aIt.Value();
420 iErr=myClsf->ErrorStatus();
422 myErrorStatus=40; // point can not be classified
428 bIsToBreak=aSC.AppendState(aSt);
436 bIsConformState=GEOMAlgo_SurfaceTools::IsConformState(aSt, myState);
437 if (myShapeType==TopAbs_EDGE) {
438 if (bIsConformState) {
442 else if (bIsConformState || aSt==TopAbs_ON) {
445 } // for (i=1; i<=aNb; ++i) next edge
447 //=======================================================================
448 //function : ProcessFaces
450 //=======================================================================
451 void GEOMAlgo_FinderShapeOn2::ProcessFaces()
455 Standard_Boolean bIsConformState, bIsToBreak, bCanBeON;
456 Standard_Integer i, aNbF, iCnt, iErr;
458 TopTools_IndexedMapOfShape aM;
459 TopExp_Explorer aExp;
460 GEOMAlgo_ListIteratorOfListOfPnt aIt;
462 TopExp::MapShapes(myShape, TopAbs_FACE, aM);
464 for (i=1; i<=aNbF; ++i) {
465 GEOMAlgo_StateCollector aSC;
466 GEOMAlgo_ListOfPnt aLP;
468 const TopoDS_Face& aF=TopoDS::Face(aM(i));
470 if (myState==GEOMAlgo_ST_ON) {
471 Handle(Geom_Surface) aS;
473 aS=BRep_Tool::Surface(aF);
474 bCanBeON=myClsf->CanBeON(aS);
481 bIsConformState=Standard_False;
483 aExp.Init(aF, TopAbs_EDGE);
484 for (; aExp.More(); aExp.Next()) {
485 const TopoDS_Shape& aE=aExp.Current();
486 bIsConformState=myMSS.Contains(aE);
487 if (!bIsConformState) {
488 break;// edge has non-conformed state
491 aSt=myMSS.FindFromKey(aE);
492 aSC.AppendState(aSt);
496 if (!bIsConformState) {
497 continue; // edge has non-conformed state,skip face
500 InnerPoints(aF, aLP);
505 bIsConformState=Standard_True;
507 for (iCnt=0; aIt.More(); aIt.Next(), ++iCnt) {
509 if (iCnt > myNbPntsMax) {
514 const gp_Pnt& aP=aIt.Value();
518 iErr=myClsf->ErrorStatus();
520 myErrorStatus=40; // point can not be classified
526 bIsToBreak=aSC.AppendState(aSt);
534 bIsConformState=GEOMAlgo_SurfaceTools::IsConformState(aSt, myState);
535 if (myShapeType==TopAbs_FACE) {
536 if (bIsConformState) {
540 else if (bIsConformState || aSt==TopAbs_ON) {
543 }// for (i=1; i<=aNb; ++i) next face
545 //=======================================================================
546 //function : ProcessSolids
548 //=======================================================================
549 void GEOMAlgo_FinderShapeOn2::ProcessSolids()
553 Standard_Boolean bIsConformState;
554 Standard_Integer i, aNbS, j, aNbF;
555 TopTools_IndexedMapOfShape aM, aMF;
558 TopExp::MapShapes(myShape, TopAbs_SOLID, aM);
560 for (i=1; i<=aNbS; ++i) {
561 GEOMAlgo_StateCollector aSC;
563 const TopoDS_Shape& aSd=aM(i);
565 TopExp::MapShapes(aSd, TopAbs_FACE, aMF);
567 bIsConformState=Standard_False;
570 for (j=1; j<=aNbF; ++j) {
571 const TopoDS_Shape& aF=aMF(j);
572 bIsConformState=myMSS.Contains(aF);
573 if (!bIsConformState) {
574 break;// face has non-conformed state
577 aSt=myMSS.FindFromKey(aF);
578 aSC.AppendState(aSt);
582 if (!bIsConformState) {
583 continue; // face has non-conformed state,skip solid
588 bIsConformState=GEOMAlgo_SurfaceTools::IsConformState(aSt, myState);
589 if (bIsConformState) {
595 //=======================================================================
596 //function : InnerPoints
598 //=======================================================================
599 void GEOMAlgo_FinderShapeOn2::InnerPoints(const TopoDS_Face& aF,
600 GEOMAlgo_ListOfPnt& aLP)
602 Standard_Integer j, j1, j2, k, n[4], aNbLinks, aNx, aNb, iCnt;//, aNbMax, *pIds;
603 TopLoc_Location aLoc;
604 Handle(Poly_Triangulation) aTRF;
605 TColStd_MapOfInteger aMBN;
606 GEOMAlgo_DataMapOfPassKeyInteger aMPKI;
607 GEOMAlgo_DataMapIteratorOfDataMapOfPassKeyInteger aIt;
614 aTRF=BRep_Tool::Triangulation(aF, aLoc);
616 if (!BuildTriangulation(aF)) {
617 myWarningStatus=20; // no triangulation found
620 aTRF=BRep_Tool::Triangulation(aF, aLoc);
623 const gp_Trsf& aTrsf=aLoc.Transformation();
624 const Poly_Array1OfTriangle& aTrs=aTRF->Triangles();
625 const TColgp_Array1OfPnt& aNodes=aTRF->Nodes();
627 // map link/nbtriangles
630 for (j=j1; j<=j2; ++j) {
631 const Poly_Triangle& aTr=aTrs(j);
632 aTr.Get(n[0], n[1], n[2]);
634 for (k=0; k<3; ++k) {
635 GEOMAlgo_PassKey aPK;
637 aPK.SetIds(n[k], n[k+1]);
638 if (aMPKI.IsBound(aPK)) {
639 Standard_Integer& iCntX=aMPKI.ChangeFind(aPK);
648 // boundary nodes aMBN
649 aNbLinks=aMPKI.Extent();
650 aIt.Initialize(aMPKI);
651 for (; aIt.More(); aIt.Next()) {
654 const GEOMAlgo_PassKey& aPK=aIt.Key();
655 aNx=(Standard_Integer)aPK.Id(1);
657 aNx=(Standard_Integer)aPK.Id(2);
663 // inner nodes=all_nodes - boundary_nodes
666 for (j=j1; j<=j2; ++j) {
667 if (!aMBN.Contains(j)) {
668 aP=aNodes(j).Transformed(aTrsf);
675 //modified by NIZNHY-PKV Mon Sep 24 08:42:32 2012f
676 if (!aNb && myNbPntsMin) { // A
677 Standard_Boolean bIsDone, bHasFirstPoint, bHasSecondPoint;
678 Standard_Integer i, aNb, aIx, /*iErr, */aNbDomains;
679 Standard_Real aUMin, aUMax, aVMin, aVMax, dU, aUx, aVx, aV1, aV2;
681 gp_Dir2d aD2D (0., 1.);
683 Handle(Geom2d_Line) aL2D;
684 Handle(Geom_Surface) aS;
688 aFF.Orientation (TopAbs_FORWARD);
690 Geom2dHatch_Hatcher& aHatcher=myContext->Hatcher(aFF);
692 aS=BRep_Tool::Surface(aFF);
693 BRepTools::UVBounds(aFF, aUMin, aUMax, aVMin, aVMax);
696 dU=(aUMax-aUMin)/aNb;
697 for (i=1; i<aNb; ++i) {
699 aP2D.SetCoord(aUx, 0.);
700 aL2D=new Geom2d_Line (aP2D, aD2D);
701 Geom2dAdaptor_Curve aHCur(aL2D);
703 aHatcher.ClrHatchings();
704 aIx=aHatcher.AddHatching(aHCur);
707 bIsDone=aHatcher.TrimDone(aIx);
713 aHatcher.ComputeDomains(aIx);
714 bIsDone=aHatcher.IsDone(aIx);
719 aNbDomains=aHatcher.NbDomains(aIx);
720 for (j=1; j<=aNbDomains; ++j) {
721 const HatchGen_Domain& aDomain=aHatcher.Domain (aIx, j) ;
723 bHasFirstPoint=aDomain.HasFirstPoint();
724 bHasSecondPoint=aDomain.HasSecondPoint();
725 if (!bHasFirstPoint || !bHasSecondPoint) {
729 aV1=aDomain.FirstPoint().Parameter();
730 aV2=aDomain.SecondPoint().Parameter();
731 aVx=IntTools_Tools::IntermediatePoint(aV1, aV2);
733 aS->D0(aUx, aVx, aPx);
737 }// for (i=1; i<aNb; ++i) {
738 }// if (!aNb && myNbPntsMin) {
740 //=======================================================================
741 //function : InnerPoints
743 //=======================================================================
744 void GEOMAlgo_FinderShapeOn2::InnerPoints(const TopoDS_Edge& aE,
745 GEOMAlgo_ListOfPnt& aLP)
749 Standard_Integer j, aNbNodes, aIndex, aNb;
750 Handle(Poly_PolygonOnTriangulation) aPTE;
751 Handle(Poly_Triangulation) aTRE;
752 TopLoc_Location aLoc;
756 BRep_Tool::PolygonOnTriangulation(aE, aPTE, aTRE, aLoc);
757 if (aTRE.IsNull() || aPTE.IsNull()) {
758 Handle(Poly_Polygon3D) aPE = BRep_Tool::Polygon3D(aE, aLoc);
760 if (!BuildTriangulation(aE)) {
761 myErrorStatus=20; // no triangulation found
764 aPE = BRep_Tool::Polygon3D(aE, aLoc);
766 const gp_Trsf& aTrsf=aLoc.Transformation();
767 const TColgp_Array1OfPnt& aNodes=aPE->Nodes();
769 aNbNodes=aPE->NbNodes();
770 Standard_Integer low = aNodes.Lower(), up = aNodes.Upper();
771 for (j=low+1; j<up; ++j) {
772 aP=aNodes(j).Transformed(aTrsf);
777 const gp_Trsf& aTrsf=aLoc.Transformation();
778 const TColgp_Array1OfPnt& aNodes=aTRE->Nodes();
780 aNbNodes=aPTE->NbNodes();
781 const TColStd_Array1OfInteger& aInds=aPTE->Nodes();
782 for (j=2; j<aNbNodes; ++j) {
784 aP=aNodes(aIndex).Transformed(aTrsf);
790 if (!aNb && myNbPntsMin) {
791 // try to fill it yourself
792 InnerPoints(aE, myNbPntsMin, aLP);
796 //=======================================================================
797 //function : InnerPoints
799 //=======================================================================
800 void GEOMAlgo_FinderShapeOn2::InnerPoints(const TopoDS_Edge& aE,
801 const Standard_Integer aNbPntsMin,
802 GEOMAlgo_ListOfPnt& aLP)
804 // try to fill it yourself
805 Standard_Boolean bInf1, bInf2;
806 Standard_Integer j, aNbT;
807 Standard_Real dT, aT, aT1, aT2;
809 Handle(Geom_Curve) aC3D;
811 aC3D=BRep_Tool::Curve(aE, aT1, aT2);
816 bInf1=Precision::IsNegativeInfinite(aT1);
817 bInf2=Precision::IsPositiveInfinite(aT2);
818 if (bInf1 || bInf2) {
824 for (j=1; j<=aNbPntsMin; ++j) {
831 //=======================================================================
832 //function : BuildTriangulation
834 //=======================================================================
836 GEOMAlgo_FinderShapeOn2::BuildTriangulation (const TopoDS_Shape& theShape)
838 // calculate deflection
839 Standard_Real aDeviationCoefficient = 0.001;
842 BRepBndLib::Add(theShape, B);
843 Standard_Real aXmin, aYmin, aZmin, aXmax, aYmax, aZmax;
844 B.Get(aXmin, aYmin, aZmin, aXmax, aYmax, aZmax);
846 Standard_Real dx = aXmax - aXmin, dy = aYmax - aYmin, dz = aZmax - aZmin;
847 Standard_Real aDeflection = Max(Max(dx, dy), dz) * aDeviationCoefficient * 4;
848 Standard_Real aHLRAngle = 0.349066;
850 // build triangulation
851 BRepMesh_IncrementalMesh Inc (theShape, aDeflection, Standard_False, aHLRAngle);
853 // check triangulation
854 bool isTriangulation = true;
856 TopExp_Explorer exp (theShape, TopAbs_FACE);
859 TopLoc_Location aTopLoc;
860 Handle(Poly_Triangulation) aTRF;
861 aTRF = BRep_Tool::Triangulation(TopoDS::Face(exp.Current()), aTopLoc);
863 isTriangulation = false;
866 else // no faces, try edges
868 TopExp_Explorer expe (theShape, TopAbs_EDGE);
870 isTriangulation = false;
873 TopLoc_Location aLoc;
874 Handle(Poly_Polygon3D) aPE = BRep_Tool::Polygon3D(TopoDS::Edge(expe.Current()), aLoc);
876 isTriangulation = false;
881 return isTriangulation;
889 // 12 -unallowed type of sub-shapes
890 // 13 -unallowed state
891 // 15 -unallowed surface type
892 // 20- no triangulation found
893 // 30- can not obtain the line from the link
894 // 40- point can not be classified
895 // 41- invalid data for classifier
896 // 42- can not compute hatching