1 // Created on: 2000-01-20
2 // Created by: data exchange team
3 // Copyright (c) 2000-2014 OPEN CASCADE SAS
5 // This file is part of Open CASCADE Technology software library.
7 // This library is free software; you can redistribute it and/or modify it under
8 // the terms of the GNU Lesser General Public License version 2.1 as published
9 // by the Free Software Foundation, with special exception defined in the file
10 // OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
11 // distribution for complete text of the license and disclaimer of any warranty.
13 // Alternatively, this file may be used under the terms of Open CASCADE
14 // commercial license or contractual agreement.
16 #include <ShapeAnalysis.hxx>
18 #include <Bnd_Box2d.hxx>
19 #include <BRep_Builder.hxx>
20 #include <BRep_Tool.hxx>
21 #include <BRepAdaptor_Surface.hxx>
22 #include <BRepGProp.hxx>
23 #include <BRepTools.hxx>
24 #include <BRepTopAdaptor_FClass2d.hxx>
25 #include <Geom2d_Curve.hxx>
26 #include <Geom_Surface.hxx>
27 #include <gp_Pnt2d.hxx>
28 #include <GProp_GProps.hxx>
29 #include <ShapeAnalysis_Curve.hxx>
30 #include <ShapeAnalysis_Edge.hxx>
31 #include <ShapeExtend_WireData.hxx>
32 #include <TColgp_SequenceOfPnt.hxx>
33 #include <TColgp_SequenceOfPnt2d.hxx>
35 #include <TopExp_Explorer.hxx>
37 #include <TopoDS_Edge.hxx>
38 #include <TopoDS_Face.hxx>
39 #include <TopoDS_Iterator.hxx>
40 #include <TopoDS_Shape.hxx>
41 #include <TopoDS_Vertex.hxx>
42 #include <TopoDS_Wire.hxx>
44 // PLANTAGE IsOuterBound, 15-SEP-1998
45 //static Standard_Integer numpb = 0;
46 //=======================================================================
47 //function : AdjustByPeriod
49 //=======================================================================
50 Standard_Real ShapeAnalysis::AdjustByPeriod(const Standard_Real Val,
51 const Standard_Real ToVal,
52 const Standard_Real Period)
54 Standard_Real diff = Val - ToVal;
55 Standard_Real D = Abs ( diff );
56 Standard_Real P = Abs ( Period );
57 if ( D <= 0.5 * P ) return 0.;
58 if ( P < 1e-100 ) return diff;
59 return ( diff >0 ? -P : P ) * floor( D / P + 0.5 );
62 //=======================================================================
63 //function : AdjustToPeriod
65 //=======================================================================
67 Standard_Real ShapeAnalysis::AdjustToPeriod(const Standard_Real Val,
68 const Standard_Real ValMin,
69 const Standard_Real ValMax)
71 return AdjustByPeriod ( Val, 0.5 * ( ValMin + ValMax ), ValMax - ValMin );
74 //=======================================================================
75 //function : FindBounds
77 //=======================================================================
79 void ShapeAnalysis::FindBounds(const TopoDS_Shape& shape,TopoDS_Vertex& V1,TopoDS_Vertex& V2)
83 ShapeAnalysis_Edge EA;
84 if (shape.ShapeType() == TopAbs_WIRE) {
85 TopoDS_Wire W = TopoDS::Wire(shape);
86 //invalid work with reversed wires replaced on TopExp
87 TopExp::Vertices(W,V1,V2);
88 //invalid work with reversed wires
89 /*TopoDS_Iterator iterWire(W);
90 //szv#4:S4163:12Mar99 optimized
91 if (iterWire.More()) {
92 TopoDS_Edge E = TopoDS::Edge (iterWire.Value());
93 V1 = EA.FirstVertex (E); iterWire.Next();
94 for ( ; iterWire.More(); iterWire.Next() ) E = TopoDS::Edge (iterWire.Value());
95 V2 = EA.LastVertex (E);
98 else if (shape.ShapeType() == TopAbs_EDGE) {
99 V1 = EA.FirstVertex (TopoDS::Edge (shape));
100 V2 = EA.LastVertex (TopoDS::Edge (shape));
102 else if (shape.ShapeType() == TopAbs_VERTEX)
103 V1 = V2 = TopoDS::Vertex (shape);
107 //=======================================================================
108 //function : ReverceSeq
109 //purpose : auxiliary
110 //=======================================================================
111 template<class HSequence>
112 static inline void ReverseSeq (HSequence& Seq)
114 Standard_Integer j=Seq.Length();
115 for(Standard_Integer i=1; i<Seq.Length(); i++) {
121 //=======================================================================
122 //function : TotCross2D
124 //=======================================================================
126 Standard_Real ShapeAnalysis::TotCross2D(const Handle(ShapeExtend_WireData)& sewd,
127 const TopoDS_Face& aFace)
129 Standard_Integer i, nbc = 0;
130 gp_Pnt2d fuv,luv, uv0;
131 Standard_Real totcross=0;
132 for(i=1; i<=sewd->NbEdges(); i++) {
133 TopoDS_Edge edge = sewd->Edge(i);
134 Standard_Real f2d, l2d;
135 Handle(Geom2d_Curve) c2d = BRep_Tool::CurveOnSurface(edge,aFace,f2d,l2d);
136 if ( !c2d.IsNull() ) {
138 TColgp_SequenceOfPnt2d SeqPnt;
139 ShapeAnalysis_Curve::GetSamplePoints (c2d, f2d, l2d, SeqPnt);
140 if( edge.Orientation()==1 )
146 Standard_Integer j=1;
147 for( ; j<=SeqPnt.Length(); j++) {
148 luv = SeqPnt.Value(j);
149 totcross += (fuv.X()-luv.X())*(fuv.Y()+luv.Y())/2;
154 totcross += (fuv.X()-uv0.X())*(fuv.Y()+uv0.Y())/2;
158 //=======================================================================
159 //function : ContourArea
161 //=======================================================================
163 Standard_Real ShapeAnalysis::ContourArea(const TopoDS_Wire& theWire)
164 //const Handle(ShapeExtend_WireData)& sewd)
167 Standard_Integer nbc = 0;
169 //Standard_Real totcross=0;
170 gp_XYZ aTotal(0.,0.,0.);
171 TopoDS_Iterator aIte(theWire,Standard_False);
172 //for(i=1; i<=sewd->NbEdges(); i++) {
173 for( ; aIte.More(); aIte.Next()) {
174 TopoDS_Edge edge = TopoDS::Edge(aIte.Value()); //sewd->Edge(i);
175 Standard_Real first, last;
176 Handle(Geom_Curve) c3d = BRep_Tool::Curve(edge,first, last);
177 if ( !c3d.IsNull() ) {
179 TColgp_SequenceOfPnt aSeqPnt;
180 if(!ShapeAnalysis_Curve::GetSamplePoints (c3d, first, last, aSeqPnt))
183 if( edge.Orientation()==TopAbs_REVERSED )
186 fuv=aSeqPnt.Value(1);
189 Standard_Integer j=1;
190 for( ; j<=aSeqPnt.Length(); j++) {
191 luv = aSeqPnt.Value(j);
192 aTotal += luv.XYZ()^ fuv.XYZ();//
197 aTotal += uv0.XYZ()^fuv.XYZ();//
198 Standard_Real anArea = aTotal.Modulus()*0.5;
201 //=======================================================================
202 //function : IsOuterBound
204 //=======================================================================
206 Standard_Boolean ShapeAnalysis::IsOuterBound(const TopoDS_Face& face)
208 TopoDS_Face F = face;
210 F.Orientation(TopAbs_FORWARD);
211 Standard_Integer nbw = 0;
212 for (TopExp_Explorer exp(F,TopAbs_WIRE); exp.More(); exp.Next()) {
213 W = TopoDS::Wire (exp.Current()); nbw ++;
217 Handle(ShapeExtend_WireData) sewd = new ShapeExtend_WireData(W);
218 Standard_Real totcross = TotCross2D(sewd,F);
219 return (totcross >= 0);
222 BRepAdaptor_Surface Ads ( F, Standard_False );
223 Standard_Real tol = BRep_Tool::Tolerance(F);
224 Standard_Real toluv = Min ( Ads.UResolution(tol), Ads.VResolution(tol) );
225 BRepTopAdaptor_FClass2d fcl (F,toluv);
226 Standard_Boolean rescl = (fcl.PerformInfinitePoint () == TopAbs_OUT);
231 //=======================================================================
232 //function : OuterBound
233 //purpose : replacement of bad BRepTools::OuterBound(), to be merged
234 // - skips internal vertices in face, if any, without exception
235 // - returns positively oriented wire rather than greater one
236 //=======================================================================
238 TopoDS_Wire ShapeAnalysis::OuterWire(const TopoDS_Face& face)
240 TopoDS_Face F = face;
241 F.Orientation(TopAbs_FORWARD);
244 TopoDS_Iterator anIt (F, Standard_False);
247 TopoDS_Shape aWire = anIt.Value();
250 // skip possible internal vertices in face
251 if (aWire.ShapeType() != TopAbs_WIRE)
254 // if current wire is the last one, return it without analysis
256 return TopoDS::Wire (aWire);
258 TopoDS_Shape aTestFace = F.EmptyCopied();
259 B.Add (aTestFace, aWire);
260 if (ShapeAnalysis::IsOuterBound (TopoDS::Face (aTestFace)))
261 return TopoDS::Wire (aWire);
263 return TopoDS_Wire();
266 //=======================================================================
267 //function : GetFaceUVBounds
269 //=======================================================================
271 void ShapeAnalysis::GetFaceUVBounds (const TopoDS_Face& F,
272 Standard_Real& UMin, Standard_Real& UMax,
273 Standard_Real& VMin, Standard_Real& VMax)
276 FF.Orientation(TopAbs_FORWARD);
277 TopExp_Explorer ex(FF,TopAbs_EDGE);
280 BRep_Tool::Surface(F,L)->Bounds(UMin,UMax,VMin,VMax);
285 ShapeAnalysis_Edge sae;
286 ShapeAnalysis_Curve sac;
287 for (;ex.More();ex.Next()) {
288 TopoDS_Edge edge = TopoDS::Edge(ex.Current());
289 Handle(Geom2d_Curve) c2d;
291 if ( ! sae.PCurve ( edge, F, c2d, f, l, Standard_False ) ) continue;
292 sac.FillBndBox ( c2d, f, l, 20, Standard_True, B );
294 B.Get(UMin,VMin,UMax,VMax);