1 // Created on: 2000-02-05
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 //06.01.99 pdn renaming ShapeFix_Wire::FixLittle to ShapeFix_Wire::FixSmall
17 //:n1 abv 20.01.99: BUC60328.rle (loopback): call FixSmall with Max(1.,preci)
18 //smh #1 11.03.99 PRO15640/15641, szv#2 PRO17393: call FixSameParameter after BuildCurve3d
19 //#74 rln 10.03.99 S4135: handling use of BRepLib::SameParameter by new static parameter
20 // pdn 18.03.99 S4135: using mintol instead of resolution from IGES file
21 // pdn 18.03.99 S4135: projecting with resolution from IGES file.
22 //%14 pdn 06.03.99 implementing fixFace in IGES
23 // S4135 pdn improvements in using of stdsameparameter flag
24 //#21 gka 12.04.99 CSR UKI60998 entities number - 13, 24 lost of boundaries during translation of tabulated cylinders
25 //S4181 pdn 15.04.99 implementing of reading IGES elementary surfaces. (instead of shift, reverce and
26 //scale factors the transformation matrix and scale factor used)
28 #include <BRep_Builder.hxx>
29 #include <BRep_Tool.hxx>
30 #include <Geom2d_Curve.hxx>
31 #include <Geom_Curve.hxx>
32 #include <Geom_Plane.hxx>
33 #include <GeomAdaptor_Curve.hxx>
34 #include <IGESControl_IGESBoundary.hxx>
35 #include <IGESData_IGESEntity.hxx>
36 #include <IGESGeom_BSplineCurve.hxx>
37 #include <IGESToBRep.hxx>
38 #include <IGESToBRep_CurveAndSurface.hxx>
39 #include <IGESToBRep_TopoCurve.hxx>
40 #include <Interface_Static.hxx>
41 #include <Message_Msg.hxx>
42 #include <Precision.hxx>
43 #include <ShapeAlgo.hxx>
44 #include <ShapeAlgo_AlgoContainer.hxx>
45 #include <ShapeAlgo_ToolContainer.hxx>
46 #include <ShapeAnalysis_ShapeTolerance.hxx>
47 #include <ShapeAnalysis_Wire.hxx>
48 #include <ShapeBuild_Edge.hxx>
49 #include <ShapeExtend_WireData.hxx>
50 #include <ShapeFix_Edge.hxx>
51 #include <ShapeFix_ShapeTolerance.hxx>
52 #include <ShapeFix_Wire.hxx>
53 #include <Standard_Type.hxx>
54 #include <TColStd_HSequenceOfTransient.hxx>
55 #include <TopoDS_Edge.hxx>
56 #include <TopoDS_Wire.hxx>
58 //=======================================================================
59 //function : IGESControl_IGESBoundary
61 //=======================================================================
62 IGESControl_IGESBoundary::IGESControl_IGESBoundary() : IGESToBRep_IGESBoundary()
66 //=======================================================================
67 //function : IGESControl_IGESBoundary
69 //=======================================================================
71 IGESControl_IGESBoundary::IGESControl_IGESBoundary(const IGESToBRep_CurveAndSurface& CS) :
72 IGESToBRep_IGESBoundary (CS)
76 //=======================================================================
79 //=======================================================================
81 void IGESControl_IGESBoundary::Check(const Standard_Boolean result,const Standard_Boolean checkclosure,
82 const Standard_Boolean aokCurve3d, const Standard_Boolean aokCurve2d)
84 Standard_Boolean Result = result;
85 Standard_Boolean okCurve3d = aokCurve3d, okCurve2d = aokCurve2d;
86 Standard_Real maxtol = myCS.GetMaxTol();
88 if (Result && checkclosure) {
89 //USA60022 7277 check of closure
90 Handle(ShapeAnalysis_Wire) saw = new ShapeAnalysis_Wire;
92 saw->SetPrecision (maxtol);
93 saw->CheckConnected (1);
94 if (saw->LastCheckStatus (ShapeExtend_FAIL)) {
96 saw->CheckConnected (1);
97 if (saw->LastCheckStatus (ShapeExtend_FAIL)) okCurve3d = Standard_False;
98 else okCurve2d = Standard_False;
99 Result = Standard_False;
104 if (okCurve3d && mysewd3d->NbEdges() > 0) {
105 Message_Msg Msg1070("IGES_1070");//"Representations in the file are inconsistent. Recomputation from 3d"
107 myCS.SendWarning(myentity,Msg1070);
110 else if (okCurve2d && mysewd2d->NbEdges() > 0) {
111 Message_Msg Msg1070("IGES_1070");//"Representations in the file are inconsistent. Recomputation from 2d"
113 myCS.SendWarning(myentity,Msg1070);
119 //=======================================================================
121 //purpose : Connects theNextWD to theWD using theSAW.
122 // First, connects edges of theNextWD by calling ShapeFix_Wire::FixConnected(). This
123 // is necessary when theNextWD was built using multiple curves from the Composite
124 // Curve (as ShapeExtend_WireData::Wire() would otherwise produce a wrong
125 // disconnected TopoDS_Wire).
126 // FixConnected() will only update the edges resulting from different composite
127 // curve segments. Edges resulting from splitting C0 curve will already be
129 //=======================================================================
130 static Standard_Boolean Connect (const Handle(ShapeAnalysis_Wire)& theSAW,
131 const Handle(ShapeExtend_WireData)& theWD,
132 const Handle(ShapeExtend_WireData)& theNextWD,
133 const Standard_Boolean theConnectNextWD,
134 const Standard_Real theMaxTol,
135 Standard_Real& theDistMin,
136 Standard_Boolean& theReverseWD,
137 Standard_Boolean& theReverseNextWD)
139 theSAW->Load (theWD);
140 if (theConnectNextWD) {
141 Handle(ShapeFix_Wire) sfw = new ShapeFix_Wire;
142 sfw->Load (theNextWD);
143 sfw->ClosedWireMode() = Standard_False; //internal connections are enough
146 return ShapeAlgo::AlgoContainer()->ConnectNextWire (theSAW, theNextWD,
147 theMaxTol, theDistMin, theReverseWD, theReverseNextWD);
150 //=======================================================================
151 //function : Transfer
153 //=======================================================================
155 Standard_Boolean IGESControl_IGESBoundary::Transfer(Standard_Boolean& okCurve,
156 Standard_Boolean& okCurve3d,
157 Standard_Boolean& okCurve2d,
158 const Handle(IGESData_IGESEntity)& icurve3d,
159 const Handle(ShapeExtend_WireData)& scurve3d,
160 const Standard_Boolean usescurve,
161 const Standard_Boolean toreverse3d,
162 const Handle(IGESData_HArray1OfIGESEntity)& curves2d,
163 const Standard_Boolean toreverse2d,
164 const Standard_Integer number,
165 Handle(ShapeExtend_WireData)& Gsewd)
167 Gsewd = new ShapeExtend_WireData;//local translation (for mysewd)
168 Handle(ShapeExtend_WireData) Gsewd3d = new ShapeExtend_WireData;//local translation (for mysewd3d)
169 Handle(ShapeExtend_WireData) Gsewd2d = new ShapeExtend_WireData;//local translation (for mysewd2d)
171 Standard_Boolean revsewd, revnextsewd;
172 Standard_Real distmin, precision = myCS.GetEpsGeom() * myCS.GetUnitFactor(), maxtol = myCS.GetMaxTol();
174 Handle(ShapeAnalysis_Wire) saw = new ShapeAnalysis_Wire,
175 saw3d = new ShapeAnalysis_Wire,
176 saw2d = new ShapeAnalysis_Wire;
177 saw->Load (Gsewd); saw->SetPrecision (precision);
178 saw3d->Load (Gsewd3d); saw3d->SetPrecision (precision);
179 saw2d->Load (Gsewd2d); saw2d->SetPrecision (precision);
181 Standard_Boolean GTranslate3d = Standard_True, GTranslate2d = Standard_True,
182 Preferred3d = Standard_True, Preferred2d = Standard_True;
184 Standard_Integer len3d = 0, len2d = 0;
185 Handle(TColStd_HSequenceOfTransient) seq3d, seq2d;
187 len3d = scurve3d->NbEdges();
189 IGESToBRep::IGESCurveToSequenceOfIGESCurve (icurve3d, seq3d);
190 len3d = seq3d->Length();
192 if (!curves2d.IsNull()) {
193 for (Standard_Integer i = 1; i <= curves2d->Length(); i++)
194 IGESToBRep::IGESCurveToSequenceOfIGESCurve (curves2d->Value (i), seq2d);
195 len2d = seq2d->Length();
198 Standard_Integer surfcurv = myCS.GetSurfaceCurve();
199 if ((surfcurv == -2 && len2d > 0) || len3d == 0)
200 GTranslate3d = Standard_False;
201 else if (( surfcurv == -3 && len3d > 0) || len2d == 0)
202 GTranslate2d = Standard_False;
204 if (GTranslate3d && GTranslate2d) {
205 //Setting preference in the case of inconsitency between 3D and 2D
206 if (surfcurv == 2) Preferred3d = Standard_False;
207 else if (surfcurv == 3) Preferred2d = Standard_False;
208 else if (myfilepreference == 2) Preferred3d = Standard_False;
209 else if (myfilepreference == 3) Preferred2d = Standard_False;
210 else Preferred3d = Standard_False;
212 if (GTranslate3d && GTranslate2d && len3d != len2d) {
213 GTranslate3d = Preferred3d;
214 GTranslate2d = Preferred2d;
217 IGESToBRep_TopoCurve TC (myCS);
219 if (GTranslate3d && !GTranslate2d) {
221 Gsewd->Add(scurve3d->Wire());
224 TopoDS_Shape Sh = TC.TransferTopoCurve (icurve3d);
228 ReverseCurves3d (Gsewd3d);
229 Gsewd->Add (Gsewd3d->Wire());
231 else Gsewd->Add (Sh);//Gsewd = Gsewd3d is impossible to avoid sharing of sewd (UK1.igs entity 7)
235 else if (!GTranslate3d && GTranslate2d) {
236 for (Standard_Integer i = curves2d->Lower(); i <= curves2d->Upper(); i++) {
237 TopoDS_Shape Sh = TC.Transfer2dTopoCurve (Handle(IGESData_IGESEntity)::DownCast (curves2d->Value (i)),
238 myface, mytrsf, myuFact);
239 if (!Sh.IsNull()) Gsewd2d->Add (Sh);
242 ReverseCurves2d (Gsewd2d, myface);
244 Gsewd->Add (Gsewd2d->Wire());
246 else if( GTranslate3d && GTranslate2d ) {
247 //Translate both curves 3D and 2D
248 //Suppose that i-th segment in 2D curve corresponds to i-th segment in 3D curve
249 for (Standard_Integer i = 1; i <= len3d; i++) {
250 Standard_Boolean LTranslate3d = Standard_True, LTranslate2d = Standard_True;
252 Handle(ShapeExtend_WireData) Lsewd3d = new ShapeExtend_WireData;
253 TC.SetBadCase (Standard_False); //:27
255 Lsewd3d->Add (scurve3d->Edge (i));
257 TopoDS_Shape shape3d = TC.TransferTopoCurve (Handle(IGESData_IGESEntity)::DownCast (seq3d->Value (i)));
258 if (!shape3d.IsNull()) {
259 Lsewd3d->Add (shape3d);
261 ReverseCurves3d (Lsewd3d);
264 else LTranslate3d = Standard_False;
266 Standard_Boolean bad3d = TC.BadCase(); //:27
267 okCurve3d = okCurve3d && ShapeAlgo::AlgoContainer()->ConnectNextWire (saw3d, Lsewd3d, maxtol, distmin, revsewd, revnextsewd);
269 Handle(ShapeExtend_WireData) Lsewd2d = new ShapeExtend_WireData;
270 TC.SetBadCase (Standard_False); //:27
271 TopoDS_Shape shape2d = TC.Transfer2dTopoCurve (Handle(IGESData_IGESEntity)::DownCast (seq2d->Value (i)),
272 myface, mytrsf, myuFact);
273 Standard_Boolean bad2d = TC.BadCase(); //:27
274 if (!shape2d.IsNull()) {
275 Lsewd2d->Add (shape2d);
277 ReverseCurves2d (Lsewd2d, myface);
279 okCurve2d = okCurve2d && ShapeAlgo::AlgoContainer()->ConnectNextWire (saw2d, Lsewd2d, maxtol, distmin, revsewd, revnextsewd);
281 else LTranslate2d = Standard_False;
283 // if (LTranslate3d && LTranslate2d && (Lsewd3d->NbEdges() != Lsewd2d->NbEdges() || bad3d || bad2d)) {
284 Standard_Boolean isBSpline = Standard_False;
285 if(!usescurve && !seq3d->Value (i).IsNull() && !seq2d->Value (i).IsNull())
286 isBSpline = seq3d->Value (i)->IsKind(STANDARD_TYPE(IGESGeom_BSplineCurve)) &&
287 seq2d->Value (i)->IsKind(STANDARD_TYPE(IGESGeom_BSplineCurve));
289 if (LTranslate3d && LTranslate2d &&
291 (isBSpline && (Lsewd3d->NbEdges() != Lsewd2d->NbEdges())) ||
292 (!isBSpline && (Lsewd3d->NbEdges() != 1 || Lsewd2d->NbEdges() != 1)) ||
296 LTranslate3d = Preferred3d;
297 LTranslate2d = Preferred2d;
299 Handle(ShapeExtend_WireData) Lsewd;//Lsewd3d or Lsewd2d or Lsewd3d+pcurve
300 if ( LTranslate3d && !LTranslate2d) Lsewd = Lsewd3d;
301 else if (!LTranslate3d && LTranslate2d) Lsewd = Lsewd2d;
304 //copying pcurve to edge with 3D curve
305 Handle(ShapeFix_Edge) sfe = new ShapeFix_Edge;
306 for (Standard_Integer iedge = 1; iedge <= Lsewd3d->NbEdges(); iedge++) {
307 TopoDS_Edge edge3d = Lsewd3d->Edge (iedge), edge2d = Lsewd2d->Edge (iedge);
308 if (!IGESToBRep::TransferPCurve (edge2d, edge3d, myface)) continue;
309 if (sfe->FixReversed2d (edge3d, myface)) {
311 cout << "Warning: IGESToBRep_IGESBoundary: 2D curve of edge was reversed" << endl;
314 //#74 rln 10.03.99 S4135: handling use of BRepLib::SameParameter by new static parameter
315 if (Interface_Static::IVal ("read.stdsameparameter.mode")) {
316 Standard_Real first, last;
317 BRep_Tool::Range(edge3d,first,last);
318 // pdn 08.04.99 S4135 optimizing in computation of SPTol
319 //choosing tolerance according to Approx_SameParameter: 50 * 22
320 Standard_Real SPTol = Min (precision, Abs (last - first)/1000);
322 B.SameParameter (edge3d, Standard_False);
323 sfe->FixSameParameter (edge3d, SPTol);
326 sfe->FixSameParameter (edge3d);
327 Standard_Real maxdev = BRep_Tool::Tolerance (edge3d);
328 //pdn 08.04.99 S4135 recomputing only if deviation is greater than maxtol
329 if (maxdev > maxtol) { //:e2
331 cout << "Warning: IGESToBRep_IGESBoundary: Deviation = " << maxdev << endl;
333 ShapeFix_ShapeTolerance().SetTolerance (edge3d, Precision::Confusion());
334 for (Standard_Integer ie = 1; ie <= iedge; ie++)
335 ShapeBuild_Edge().RemovePCurve (Lsewd3d->Edge (ie), myface);
338 cout << "Warning: IGESToBRep_IGESBoundary: 3D and 2D curves are inconsistent; 2D is ignored" << endl;
343 cout << "Warning: IGESToBRep_IGESBoundary: 3D and 2D curves are inconsistent; 3D is ignored" << endl;
351 okCurve = okCurve && ShapeAlgo::AlgoContainer()->ConnectNextWire (saw, Lsewd, maxtol, distmin, revsewd, revnextsewd);
354 cout << "Warning: IGESToBRep_IGESBoundary: Curves " << i - 1 << " and " << i << " cannot be connected" << endl;
356 Gsewd3d = new ShapeExtend_WireData;
357 for (Standard_Integer i = 1; i <= len3d; i++) {
359 Gsewd3d->Add (scurve3d->Edge (i));
362 TC.TransferTopoCurve (Handle(IGESData_IGESEntity)::DownCast (seq3d->Value (i)));
363 if (!Sh.IsNull()) Gsewd3d->Add (Sh);
367 ReverseCurves3d(Gsewd3d);
369 Gsewd2d = new ShapeExtend_WireData;
370 for (Standard_Integer i = 1; i <= len2d; i++) {
371 TopoDS_Shape Sh = TC.Transfer2dTopoCurve (Handle(IGESData_IGESEntity)::DownCast (seq2d->Value (i)),
372 myface, mytrsf, myuFact);
373 if (!Sh.IsNull()) Gsewd2d->Add (Sh);
376 ReverseCurves2d (Gsewd2d, myface);
378 Handle(ShapeFix_Wire) sfw3 = new ShapeFix_Wire(Gsewd3d->Wire(),myface,precision);
380 TopoDS_Wire w3 = sfw3->Wire();
381 Handle(ShapeFix_Wire) sfw2 = new ShapeFix_Wire(Gsewd2d->Wire(),myface,precision);
383 TopoDS_Wire w2 = sfw2->Wire();
384 ShapeAnalysis_ShapeTolerance ST;
385 double tol3 = ST.Tolerance(w3,1);
386 double tol2 = ST.Tolerance(w2,1);
387 Gsewd3d = new ShapeExtend_WireData;
388 Gsewd2d = new ShapeExtend_WireData;
395 okCurve = Standard_True;
396 okCurve2d = Standard_True;
397 okCurve3d = Standard_True;
403 okCurve = okCurve && Connect (saw, mysewd, Gsewd, (len3d > 1) || (len2d > 1), maxtol,
404 distmin, revsewd, revnextsewd);
405 okCurve3d = okCurve3d && Connect (saw3d, mysewd3d, Gsewd3d, len3d > 1, maxtol,
406 distmin, revsewd, revnextsewd);
407 okCurve2d = okCurve2d && Connect (saw2d, mysewd2d, Gsewd2d, len2d > 1, maxtol,
408 distmin, revsewd, revnextsewd);