0022731: Error on attempt to write in IGES 5.3 the attached brep model
[occt.git] / src / IGESControl / IGESControl_IGESBoundary.cxx
CommitLineData
7fd59977 1// File: IGESControl_IGESBoundary.cxx
2// Created: Sat Feb 5 16:35:04 2000
3// Author: data exchange team
4// <det@kinox>
5
6//06.01.99 pdn renaming ShapeFix_Wire::FixLittle to ShapeFix_Wire::FixSmall
7//:n1 abv 20.01.99: BUC60328.rle (loopback): call FixSmall with Max(1.,preci)
8//smh #1 11.03.99 PRO15640/15641, szv#2 PRO17393: call FixSameParameter after BuildCurve3d
9//#74 rln 10.03.99 S4135: handling use of BRepLib::SameParameter by new static parameter
10// pdn 18.03.99 S4135: using mintol instead of resolution from IGES file
11// pdn 18.03.99 S4135: projecting with resolution from IGES file.
12//%14 pdn 06.03.99 implementing fixFace in IGES
13// S4135 pdn improvements in using of stdsameparameter flag
14//#21 gka 12.04.99 CSR UKI60998 entities number - 13, 24 lost of boundaries during translation of tabulated cylinders
15//S4181 pdn 15.04.99 implementing of reading IGES elementary surfaces. (instead of shift, reverce and
16//scale factors the transformation matrix and scale factor used)
17
18#include <IGESControl_IGESBoundary.ixx>
19#include <TColStd_HSequenceOfTransient.hxx>
20#include <Geom2d_Curve.hxx>
21#include <Geom_Curve.hxx>
22#include <Geom_Plane.hxx>
23#include <GeomAdaptor_Curve.hxx>
24#include <Precision.hxx>
25#include <TopoDS_Edge.hxx>
26#include <TopoDS_Wire.hxx>
27#include <BRep_Builder.hxx>
28#include <BRep_Tool.hxx>
29#include <ShapeBuild_Edge.hxx>
30#include <ShapeAnalysis_Wire.hxx>
31#include <ShapeAnalysis_ShapeTolerance.hxx>
32#include <ShapeFix_Edge.hxx>
33#include <ShapeFix_Wire.hxx>
34#include <ShapeFix_ShapeTolerance.hxx>
35#include <IGESToBRep.hxx>
36#include <IGESToBRep_TopoCurve.hxx>
37#include <Message_Msg.hxx>
38#include <Interface_Static.hxx>
39#include <ShapeAlgo.hxx>
40#include <ShapeAlgo_AlgoContainer.hxx>
41#include <ShapeAlgo_ToolContainer.hxx>
42#include <IGESGeom_BSplineCurve.hxx>
43
44
45//=======================================================================
46//function : IGESControl_IGESBoundary
47//purpose :
48//=======================================================================
49
50IGESControl_IGESBoundary::IGESControl_IGESBoundary() : IGESToBRep_IGESBoundary()
51{
52}
53
54//=======================================================================
55//function : IGESControl_IGESBoundary
56//purpose :
57//=======================================================================
58
59IGESControl_IGESBoundary::IGESControl_IGESBoundary(const IGESToBRep_CurveAndSurface& CS) :
60 IGESToBRep_IGESBoundary (CS)
61{
62}
63
64//=======================================================================
65//function : Check
66//purpose :
67//=======================================================================
68
69 void IGESControl_IGESBoundary::Check(const Standard_Boolean result,const Standard_Boolean checkclosure,
70 const Standard_Boolean aokCurve3d, const Standard_Boolean aokCurve2d)
71{
72 Standard_Boolean Result = result;
73 Standard_Boolean okCurve3d = aokCurve3d, okCurve2d = aokCurve2d;
74 Standard_Real maxtol = myCS.GetMaxTol();
75
76 if (Result && checkclosure) {
77 //USA60022 7277 check of closure
78 Handle(ShapeAnalysis_Wire) saw = new ShapeAnalysis_Wire;
79 saw->Load (mysewd);
80 saw->SetPrecision (maxtol);
81 saw->CheckConnected (1);
82 if (saw->LastCheckStatus (ShapeExtend_FAIL)) {
83 saw->Load (mysewd3d);
84 saw->CheckConnected (1);
85 if (saw->LastCheckStatus (ShapeExtend_FAIL)) okCurve3d = Standard_False;
86 else okCurve2d = Standard_False;
87 Result = Standard_False;
88 }
89 }
90 if (!Result) {
91 mysewd->Clear();
92 if (okCurve3d && mysewd3d->NbEdges() > 0) {
93 Message_Msg Msg1070("IGES_1070");//"Representations in the file are inconsistent. Recomputation from 3d"
94 Msg1070.Arg(3);
95 myCS.SendWarning(myentity,Msg1070);
96 mysewd = mysewd3d;
97 }
98 else if (okCurve2d && mysewd2d->NbEdges() > 0) {
99 Message_Msg Msg1070("IGES_1070");//"Representations in the file are inconsistent. Recomputation from 2d"
100 Msg1070.Arg(2);
101 myCS.SendWarning(myentity,Msg1070);
102 mysewd = mysewd2d;
103 }
104 }
105}
106
107//=======================================================================
108//function : Transfer
109//purpose :
110//=======================================================================
111
112 Standard_Boolean IGESControl_IGESBoundary::Transfer(Standard_Boolean& okCurve,
113 Standard_Boolean& okCurve3d,
114 Standard_Boolean& okCurve2d,
115 const Handle(IGESData_IGESEntity)& icurve3d,
116 const Handle(ShapeExtend_WireData)& scurve3d,
117 const Standard_Boolean usescurve,
118 const Standard_Boolean toreverse3d,
119 const Handle(IGESData_HArray1OfIGESEntity)& curves2d,
120 const Standard_Boolean toreverse2d,
121 const Standard_Integer number,
122 Handle(ShapeExtend_WireData)& Gsewd)
123{
124 Gsewd = new ShapeExtend_WireData;//local translation (for mysewd)
125 Handle(ShapeExtend_WireData) Gsewd3d = new ShapeExtend_WireData;//local translation (for mysewd3d)
126 Handle(ShapeExtend_WireData) Gsewd2d = new ShapeExtend_WireData;//local translation (for mysewd2d)
127
128 Standard_Boolean revsewd, revnextsewd;
129 Standard_Real distmin, precision = myCS.GetEpsGeom() * myCS.GetUnitFactor(), maxtol = myCS.GetMaxTol();
130
131 Handle(ShapeAnalysis_Wire) saw = new ShapeAnalysis_Wire,
132 saw3d = new ShapeAnalysis_Wire,
133 saw2d = new ShapeAnalysis_Wire;
134 saw->Load (Gsewd); saw->SetPrecision (precision);
135 saw3d->Load (Gsewd3d); saw3d->SetPrecision (precision);
136 saw2d->Load (Gsewd2d); saw2d->SetPrecision (precision);
137
138 Standard_Boolean GTranslate3d = Standard_True, GTranslate2d = Standard_True,
139 Preferred3d = Standard_True, Preferred2d = Standard_True;
140
141 Standard_Integer len3d = 0, len2d = 0;
142 Handle(TColStd_HSequenceOfTransient) seq3d, seq2d;
143 if (usescurve)
144 len3d = scurve3d->NbEdges();
145 else {
146 IGESToBRep::IGESCurveToSequenceOfIGESCurve (icurve3d, seq3d);
147 len3d = seq3d->Length();
148 }
149 if (!curves2d.IsNull()) {
150 for (Standard_Integer i = 1; i <= curves2d->Length(); i++)
151 IGESToBRep::IGESCurveToSequenceOfIGESCurve (curves2d->Value (i), seq2d);
152 len2d = seq2d->Length();
153 }
154
155 Standard_Integer surfcurv = myCS.GetSurfaceCurve();
156 if ((surfcurv == -2 && len2d > 0) || len3d == 0)
157 GTranslate3d = Standard_False;
158 else if (( surfcurv == -3 && len3d > 0) || len2d == 0)
159 GTranslate2d = Standard_False;
160
161 if (GTranslate3d && GTranslate2d)
162 //Setting preference in the case of inconsitency between 3D and 2D
163 if (surfcurv == 2) Preferred3d = Standard_False;
164 else if (surfcurv == 3) Preferred2d = Standard_False;
165 else if (myfilepreference == 2) Preferred3d = Standard_False;
166 else if (myfilepreference == 3) Preferred2d = Standard_False;
167 else Preferred3d = Standard_False;
168
169 if (GTranslate3d && GTranslate2d && len3d != len2d) {
170 GTranslate3d = Preferred3d;
171 GTranslate2d = Preferred2d;
172 }
173
174 IGESToBRep_TopoCurve TC (myCS);
175
176 if (GTranslate3d && !GTranslate2d) {
177 if (usescurve) {
178 Gsewd->Add(scurve3d->Wire());
179 }
180 else {
181 TopoDS_Shape Sh = TC.TransferTopoCurve (icurve3d);
182 if (!Sh.IsNull()) {
183 Gsewd3d->Add (Sh);
184 if (toreverse3d) {
185 ReverseCurves3d (Gsewd3d);
186 Gsewd->Add (Gsewd3d->Wire());
187 }
188 else Gsewd->Add (Sh);//Gsewd = Gsewd3d is impossible to avoid sharing of sewd (UK1.igs entity 7)
189 }
190 }
191 }
192 else if (!GTranslate3d && GTranslate2d) {
193 for (Standard_Integer i = curves2d->Lower(); i <= curves2d->Upper(); i++) {
194 TopoDS_Shape Sh = TC.Transfer2dTopoCurve (Handle(IGESData_IGESEntity)::DownCast (curves2d->Value (i)),
195 myface, mytrsf, myuFact);
196 if (!Sh.IsNull()) Gsewd2d->Add (Sh);
197 }
198 if (toreverse2d) {
199 ReverseCurves2d (Gsewd2d, myface);
200 }
201 Gsewd->Add (Gsewd2d->Wire());
202 }
203 else if( GTranslate3d && GTranslate2d ) {
204 //Translate both curves 3D and 2D
205 //Suppose that i-th segment in 2D curve corresponds to i-th segment in 3D curve
206 for (Standard_Integer i = 1; i <= len3d; i++) {
207 Standard_Boolean LTranslate3d = Standard_True, LTranslate2d = Standard_True;
208
209 Handle(ShapeExtend_WireData) Lsewd3d = new ShapeExtend_WireData;
210 TC.SetBadCase (Standard_False); //:27
211 if (usescurve)
212 Lsewd3d->Add (scurve3d->Edge (i));
213 else {
214 TopoDS_Shape shape3d = TC.TransferTopoCurve (Handle(IGESData_IGESEntity)::DownCast (seq3d->Value (i)));
215 if (!shape3d.IsNull()) {
216 Lsewd3d->Add (shape3d);
217 if (toreverse3d) {
218 ReverseCurves3d (Lsewd3d);
219 }
220 }
221 else LTranslate3d = Standard_False;
222 }
223 Standard_Boolean bad3d = TC.BadCase(); //:27
224 okCurve3d = okCurve3d && ShapeAlgo::AlgoContainer()->ConnectNextWire (saw3d, Lsewd3d, maxtol, distmin, revsewd, revnextsewd);
225
226 Handle(ShapeExtend_WireData) Lsewd2d = new ShapeExtend_WireData;
227 TC.SetBadCase (Standard_False); //:27
228 TopoDS_Shape shape2d = TC.Transfer2dTopoCurve (Handle(IGESData_IGESEntity)::DownCast (seq2d->Value (i)),
229 myface, mytrsf, myuFact);
230 Standard_Boolean bad2d = TC.BadCase(); //:27
231 if (!shape2d.IsNull()) {
232 Lsewd2d->Add (shape2d);
233 if (toreverse2d) {
234 ReverseCurves2d (Lsewd2d, myface);
235 }
236 okCurve2d = okCurve2d && ShapeAlgo::AlgoContainer()->ConnectNextWire (saw2d, Lsewd2d, maxtol, distmin, revsewd, revnextsewd);
237 }
238 else LTranslate2d = Standard_False;
239
240// if (LTranslate3d && LTranslate2d && (Lsewd3d->NbEdges() != Lsewd2d->NbEdges() || bad3d || bad2d)) {
241 Standard_Boolean isBSpline = Standard_False;
242 if(!usescurve && !seq3d->Value (i).IsNull() && !seq2d->Value (i).IsNull())
243 isBSpline = seq3d->Value (i)->IsKind(STANDARD_TYPE(IGESGeom_BSplineCurve)) &&
244 seq2d->Value (i)->IsKind(STANDARD_TYPE(IGESGeom_BSplineCurve));
245
246 if (LTranslate3d && LTranslate2d &&
247 (
248 (isBSpline && (Lsewd3d->NbEdges() != Lsewd2d->NbEdges())) ||
249 (!isBSpline && (Lsewd3d->NbEdges() != 1 || Lsewd2d->NbEdges() != 1)) ||
250 bad3d || bad2d
251 )) {
252
253 LTranslate3d = Preferred3d;
254 LTranslate2d = Preferred2d;
255 }
256 Handle(ShapeExtend_WireData) Lsewd;//Lsewd3d or Lsewd2d or Lsewd3d+pcurve
257 if ( LTranslate3d && !LTranslate2d) Lsewd = Lsewd3d;
258 else if (!LTranslate3d && LTranslate2d) Lsewd = Lsewd2d;
259 else {
260 Lsewd = Lsewd3d;
261 //copying pcurve to edge with 3D curve
262 Handle(ShapeFix_Edge) sfe = new ShapeFix_Edge;
263 for (Standard_Integer iedge = 1; iedge <= Lsewd3d->NbEdges(); iedge++) {
264 TopoDS_Edge edge3d = Lsewd3d->Edge (iedge), edge2d = Lsewd2d->Edge (iedge);
265 if (!IGESToBRep::TransferPCurve (edge2d, edge3d, myface)) continue;
266 if (sfe->FixReversed2d (edge3d, myface)) {
267#ifdef DEB
268 cout << "Warning: IGESToBRep_IGESBoundary: 2D curve of edge was reversed" << endl;
269#endif
270 }
271 //#74 rln 10.03.99 S4135: handling use of BRepLib::SameParameter by new static parameter
272 if (Interface_Static::IVal ("read.stdsameparameter.mode")) {
273 Standard_Real first, last;
274 BRep_Tool::Range(edge3d,first,last);
275 // pdn 08.04.99 S4135 optimizing in computation of SPTol
276 //choosing tolerance according to Approx_SameParameter: 50 * 22
277 Standard_Real SPTol = Min (precision, Abs (last - first)/1000);
278 BRep_Builder B;
279 B.SameParameter (edge3d, Standard_False);
280 sfe->FixSameParameter (edge3d, SPTol);
281 }
282 else
283 sfe->FixSameParameter (edge3d);
284 Standard_Real maxdev = BRep_Tool::Tolerance (edge3d);
285 //pdn 08.04.99 S4135 recomputing only if deviation is greater than maxtol
286 if (maxdev > maxtol) { //:e2
287#ifdef DEB
288 cout << "Warning: IGESToBRep_IGESBoundary: Deviation = " << maxdev << endl;
289#endif
290 ShapeFix_ShapeTolerance().SetTolerance (edge3d, Precision::Confusion());
291 for (Standard_Integer ie = 1; ie <= iedge; ie++)
292 ShapeBuild_Edge().RemovePCurve (Lsewd3d->Edge (ie), myface);
293 if (Preferred3d) {
294#ifdef DEB
295 cout << "Warning: IGESToBRep_IGESBoundary: 3D and 2D curves are inconsistent; 2D is ignored" << endl;
296#endif
297 }
298 else {
299#ifdef DEB
300 cout << "Warning: IGESToBRep_IGESBoundary: 3D and 2D curves are inconsistent; 3D is ignored" << endl;
301#endif
302 Lsewd = Lsewd2d;
303 }
304 break;
305 }
306 }
307 }
308 okCurve = okCurve && ShapeAlgo::AlgoContainer()->ConnectNextWire (saw, Lsewd, maxtol, distmin, revsewd, revnextsewd);
309 if (!okCurve) {
310#ifdef DEB
311 cout << "Warning: IGESToBRep_IGESBoundary: Curves " << i - 1 << " and " << i << " cannot be connected" << endl;
312#endif
313 Gsewd3d = new ShapeExtend_WireData;
314 for (Standard_Integer i = 1; i <= len3d; i++) {
315 if (usescurve)
316 Gsewd3d->Add (scurve3d->Edge (i));
317 else {
318 TopoDS_Shape Sh =
319 TC.TransferTopoCurve (Handle(IGESData_IGESEntity)::DownCast (seq3d->Value (i)));
320 if (!Sh.IsNull()) Gsewd3d->Add (Sh);
321 }
322 }
323 if (toreverse3d) {
324 ReverseCurves3d(Gsewd3d);
325 }
326 Gsewd2d = new ShapeExtend_WireData;
327 for (Standard_Integer i = 1; i <= len2d; i++) {
328 TopoDS_Shape Sh = TC.Transfer2dTopoCurve (Handle(IGESData_IGESEntity)::DownCast (seq2d->Value (i)),
329 myface, mytrsf, myuFact);
330 if (!Sh.IsNull()) Gsewd2d->Add (Sh);
331 }
332 if (toreverse2d) {
333 ReverseCurves2d (Gsewd2d, myface);
334 }
335 Handle(ShapeFix_Wire) sfw3 = new ShapeFix_Wire(Gsewd3d->Wire(),myface,precision);
336 sfw3->Perform();
337 TopoDS_Wire w3 = sfw3->Wire();
338 Handle(ShapeFix_Wire) sfw2 = new ShapeFix_Wire(Gsewd2d->Wire(),myface,precision);
339 sfw2->Perform();
340 TopoDS_Wire w2 = sfw2->Wire();
341 ShapeAnalysis_ShapeTolerance ST;
342 double tol3 = ST.Tolerance(w3,1);
343 double tol2 = ST.Tolerance(w2,1);
344 Gsewd3d = new ShapeExtend_WireData;
345 Gsewd2d = new ShapeExtend_WireData;
346 Gsewd3d->Add(w3);
347 Gsewd2d->Add(w3);
348 if(tol3<tol2)
349 Gsewd->Add(w3);
350 else
351 Gsewd->Add(w2);
352 okCurve = Standard_True;
353 okCurve2d = Standard_True;
354 okCurve3d = Standard_True;
355 }
356 }
357 }
358
359 if (number > 1) {
360 saw->Load (mysewd);
361 okCurve = okCurve &&
362 ShapeAlgo::AlgoContainer()->ConnectNextWire (saw, Gsewd, maxtol,
363 distmin, revsewd, revnextsewd);
364 saw3d->Load (mysewd3d);
365 okCurve3d = okCurve3d &&
366 ShapeAlgo::AlgoContainer()->ConnectNextWire (saw3d, Gsewd3d, maxtol,
367 distmin, revsewd, revnextsewd);
368 saw2d->Load (mysewd2d);
369 okCurve2d = okCurve2d &&
370 ShapeAlgo::AlgoContainer()->ConnectNextWire (saw2d, Gsewd2d, maxtol,
371 distmin, revsewd, revnextsewd);
372 }
373 else {
374 mysewd = Gsewd;
375 mysewd3d = Gsewd3d;
376 mysewd2d = Gsewd2d;
377 }
378 return okCurve;
379}
380