0022726: Exception on restoring shape
[occt.git] / src / IGESToBRep / IGESToBRep_Reader.cxx
CommitLineData
7fd59977 1//pdn 11.01.99 including <stdio.h> for compilation on NT
2//#70 rln 03.03.99 syntax correction
3// sln 11.06.2002 OCC448 : Initialize "read.onlyvisiable" parameter to control transfering invisiable sub entities which logicaly depend on the grouping entities
4#include <stdio.h>
5#include <IGESToBRep_Reader.ixx>
6#include <Standard_ErrorHandler.hxx>
7#include <Standard_Failure.hxx>
8#include <OSD_Timer.hxx>
9
10#include <gp_Trsf.hxx>
11
12#include <TopAbs.hxx>
13#include <TopoDS_Compound.hxx>
14#include <TopoDS_Shape.hxx>
15#include <BRep_Builder.hxx>
16#include <BRepLib.hxx>
17#include <BRepTools_Modifier.hxx>
18
19#include <Message_Msg.hxx>
20#include <Message_Messenger.hxx>
21
22#include <IGESFile_Read.hxx>
23#include <IGESData_FileProtocol.hxx>
24#include <IGESData_GlobalSection.hxx>
25#include <IGESData_IGESEntity.hxx>
26#include <IGESSolid.hxx>
27#include <IGESSolid_Protocol.hxx>
28#include <IGESAppli.hxx>
29#include <IGESAppli_Protocol.hxx>
30
31#include <Interface_Macros.hxx>
32#include <Interface_CheckTool.hxx>
33#include <Interface_CheckIterator.hxx>
34#include <Interface_ShareFlags.hxx>
35#include <Interface_Static.hxx>
36#include <Interface_Check.hxx>
37
38#include <IGESToBRep.hxx>
39#include <IGESToBRep_Actor.hxx>
40#include <IGESToBRep_CurveAndSurface.hxx>
41
42//#include <ShapeCustom.hxx>
43#include <ShapeExtend_Explorer.hxx>
44#include <ShapeFix_ShapeTolerance.hxx>
45
46#include <Transfer_TransferOutput.hxx>
47#include <Transfer_IteratorOfProcessForTransient.hxx>
48#include <TransferBRep.hxx>
49#include <TransferBRep_ShapeBinder.hxx>
50#include <TransferBRep_ShapeListBinder.hxx>
51#include <XSAlgo.hxx>
52#include <XSAlgo_AlgoContainer.hxx>
53
54#include <ShapeAlgo.hxx>
55#include <ShapeAlgo_AlgoContainer.hxx>
56#include <Message_ProgressSentry.hxx>
57
58#ifdef WNT
59#include <stdlib.h>
60#else
61#include <errno.h>
62#endif
63//extern int errno;
64
65static Handle(IGESData_FileProtocol) protocol;
66
67
68//=======================================================================
69//function : IGESToBRep_Reader
70//purpose :
71//=======================================================================
72 IGESToBRep_Reader::IGESToBRep_Reader ()
73{
74 theDone = Standard_False;
75 if (protocol.IsNull()) {
76 IGESAppli::Init(); IGESSolid::Init();
77 protocol = new IGESData_FileProtocol;
78 protocol->Add(IGESAppli::Protocol());
79 protocol->Add(IGESSolid::Protocol());
80 }
81 theActor = new IGESToBRep_Actor;
82 theProc = new Transfer_TransientProcess;
83}
84
85
86//=======================================================================
87//function : LoadFile
88//purpose : loads a Model from a file
89//=======================================================================
90
91Standard_Integer IGESToBRep_Reader::LoadFile (const Standard_CString filename)
92{
93 if ( theProc.IsNull() )
94 theProc = new Transfer_TransientProcess;
95 Handle(Message_Messenger) TF = theProc->Messenger();
96
97 // Message for Diagnostic file.
98 Message_Msg msg2000("IGES_2000");
99 msg2000.Arg(filename);
100 TF->Send (msg2000, Message_Info);
101 //Message_Msg msg2001("IGES_2001"); // Date
102 Message_Msg msg2005("IGES_2005");
103 msg2005.Arg(theProc->TraceLevel());
104 TF->Send (msg2005, Message_Info);
105 /////////////////////////////////////////////////////////
106 Handle(IGESData_IGESModel) model = new IGESData_IGESModel;
107
108 OSD_Timer c; c.Reset(); c.Start();
109 char *pfilename=(char *)filename;
110 Standard_Integer StatusFile = IGESFile_Read(pfilename,model,protocol);
111 if (StatusFile != 0) {
112 // Sending of message : IGES file opening error
113 Message_Msg Msg2("XSTEP_2");
114 TF->Send (Msg2, Message_Info);
115 //Message_Msg Msg3("XSTEP_3");
116 //Message_Msg Msg4("XSTEP_4");
117 //Message_Msg Msg5("XSTEP_5");
118 //Message_Msg Msg6("XSTEP_6");
119 //Message_Msg Msg7("XSTEP_7");
120 // Reasons of the file opening error
121 switch(errno)
122 {
123 case 2 : // Sending of message : No such file or directory
124 {
125 Message_Msg Msg3("XSTEP_3");
126 TF->Send (Msg3, Message_Info);
127 }
128 break;
129 case 12 : // Sending of message : Not enough space
130 {
131 Message_Msg Msg4("XSTEP_4");
132 TF->Send (Msg4, Message_Info);
133 }
134 break;
135 case 13 : // Sending of message : Permission Denied
136 {
137 Message_Msg Msg5("XSTEP_5");
138 TF->Send (Msg5, Message_Info);
139 }
140 break;
141 case 24 : // Sending of message : Too many open files
142 {
143 Message_Msg Msg6("XSTEP_6");
144 TF->Send (Msg6, Message_Info);
145 }
146 break;
147 default : // Sending of message : No determined
148 {
149 Message_Msg Msg7("XSTEP_7");
150 TF->Send (Msg7, Message_Info);
151 }
152 break;
153 }
154 }
155
156 Message_Msg Msg8 ("XSTEP_8");
157 Message_Msg Msg25 ("XSTEP_25");
158 Message_Msg Msg26 ("XSTEP_26");
159 // Nb warning in global section.
160
161 Standard_Integer nbWarn = 0,nbFail = 0;
162 // Add the number of warning on enities :
163 Interface_CheckTool cht (model,protocol);
164 Interface_CheckIterator anIter = cht.CompleteCheckList();
165 for(anIter.Start(); anIter.More(); anIter.Next()) {
166 const Handle(Interface_Check) ach = anIter.Value();
167 nbWarn += ach->NbWarnings();
168 nbFail += ach->NbFails();
169 }
170// Messages nbWarn and nbFail;
171 Msg25.Arg(nbFail);
172 Msg26.Arg(nbWarn);
173 TF->Send (Msg25, Message_Info);
174 TF->Send (Msg26, Message_Info);
175
176 // Message fin de loading iGES file (elapsed time %s)
177 char t[20];
178 t[0]='\0';
179 Standard_Real second, cpu;
180 Standard_Integer minute, hour;
181 c.Show(second, minute, hour,cpu);
182 if (hour > 0)
183 sprintf(t,"%dh:%dm:%.2fs",hour,minute,second);
184 else if (minute > 0)
185 sprintf(t,"%dm:%.2fs",minute,second);
186 else
187 sprintf(t,"%.2fs",second);
188 // Sending of message : End of Loading
189 Msg8.Arg(t);
190 TF->Send (Msg8, Message_Info);
191
192 SetModel(model);
193 return StatusFile;
194}
195
196
197//=======================================================================
198//function : SetModel
199//purpose : Specifies a Model to work on
200//=======================================================================
201 void IGESToBRep_Reader::SetModel (const Handle(IGESData_IGESModel)& model)
202{
203 theModel = model;
204 theDone = Standard_False;
205 theShapes.Clear();
206 if ( theProc.IsNull() )
207 theProc = new Transfer_TransientProcess (theModel->NbEntities());
208 else
209 theProc->Clear();
210}
211
212
213//=======================================================================
214//function : Model
215//purpose : returns the Model to be worked on
216//=======================================================================
217 Handle(IGESData_IGESModel) IGESToBRep_Reader::Model () const
218 { return theModel; }
219
220
221//=======================================================================
222//function : SetTransientProcess
223//purpose : Specifies a TransferProcess
224//=======================================================================
225 void IGESToBRep_Reader::SetTransientProcess
226 (const Handle(Transfer_TransientProcess)& TP)
227 { theProc = TP; }
228
229//=======================================================================
230//function : TransientProcess
231//purpose : Returns the TransferProcess
232//=======================================================================
233 Handle(Transfer_TransientProcess) IGESToBRep_Reader::TransientProcess () const
234 { return theProc; }
235
236//=======================================================================
237//function : Actor
238//purpose : returns theActor
239//=======================================================================
240 Handle(IGESToBRep_Actor) IGESToBRep_Reader::Actor () const
241 { return theActor; }
242
243
244//=======================================================================
245//function : Clear
246//purpose : Clears the result and Done status
247//=======================================================================
248 void IGESToBRep_Reader::Clear ()
249{
250 theDone = Standard_False;
251 theShapes.Clear();
252}
253
254
255//=======================================================================
256//function : Check
257//purpose : Checks the Model
258//=======================================================================
259 Standard_Boolean IGESToBRep_Reader::Check
260 (const Standard_Boolean withprint) const
261{
262 Interface_CheckTool cht (theModel,protocol);
263 Interface_CheckIterator chl = cht.CompleteCheckList();
264 if (withprint && !theProc.IsNull())
265 cht.Print(chl, theProc->Messenger());
266 return chl.IsEmpty(Standard_True);
267}
268
269
270//=======================================================================
271//function : IsDone
272//purpose : returns True if the last transfert was a success
273//=======================================================================
274 Standard_Boolean IGESToBRep_Reader::IsDone () const
275 { return theDone; }
276
277
278//=======================================================================
279//function : EncodeRegul
280//purpose : INTERNAL to encode regularity on edges
281//=======================================================================
282
283static Standard_Boolean EncodeRegul (const TopoDS_Shape& sh)
284{
285 Standard_Real tolang = Interface_Static::RVal("read.encoderegularity.angle");
286 if (sh.IsNull()) return Standard_True;
287 if (tolang <= 0) return Standard_True;
288 try {
289 OCC_CATCH_SIGNALS
290 BRepLib::EncodeRegularity (sh,tolang);
291 }
292 catch(Standard_Failure) {
293 return Standard_False;
294 }
295 return Standard_True;
296}
297
298//=======================================================================
299//function : UpdateMap
300//purpose : Updates the correspondence map (Transfer_TransientProcess),
301// setting as translation results, the shapes received after
302// modification by modifier (BRepTools_Modifier)
303//warning : BRepTools_Modifier raises exception when it cannot find input
304// shape in its internal list
305//=======================================================================
306
307// coment as unused PTV 18.09.2000
308// static void UpdateMap (const Handle(Transfer_TransientProcess)& map,
309// const BRepTools_Modifier& modifier)
310// {
311// Transfer_IteratorOfProcessForTransient iterator = map->CompleteResult(Standard_True);
312// for (iterator.Start(); iterator.More(); iterator.Next()) {
313// const Handle(Transfer_Binder) binder = iterator.Value();
314// try { //to avoid exception in BRepTools_Modifier
315// OCC_CATCH_SIGNALS
316// if (binder->IsKind (STANDARD_TYPE (TransferBRep_ShapeBinder))) {
317// DeclareAndCast(TransferBRep_ShapeBinder, shapebinder, binder);
318// if (shapebinder->HasResult()) {
319// TopoDS_Shape result = shapebinder->Result();
320// TopoDS_Shape modified = modifier.ModifiedShape (result);
321// if (shapebinder->Status() != Transfer_StatusUsed) //to avoid exception
322// shapebinder->SetResult (modified);
323// }
324// }
325// else if (binder->IsKind (STANDARD_TYPE (TransferBRep_ShapeListBinder))) {
326// DeclareAndCast(TransferBRep_ShapeListBinder, shapelistbinder, binder);
327// for (Standard_Integer i = 1; i <= shapelistbinder->NbShapes(); i++) {
328// TopoDS_Shape result = shapelistbinder->Shape (i);
329// TopoDS_Shape modified = modifier.ModifiedShape (result);
330// shapelistbinder->SetResult (i, modified);
331// }
332// }
333// }
334// catch(Standard_Failure) {
335// continue;
336// }
337// }
338// }
339
340//=======================================================================
341//function : TrimTolerances
342//purpose : Trims tolerances of the shape according to static parameters
343//
344//=======================================================================
345
346static void TrimTolerances (const TopoDS_Shape& shape,
347 const Standard_Real tol)
348{
349 if( Interface_Static::IVal("read.maxprecision.mode")==1) {
350 ShapeFix_ShapeTolerance SFST;
351 SFST.LimitTolerance (shape, 0, Max(tol,Interface_Static::RVal ("read.maxprecision.val")));
352 }
353}
354
355//=======================================================================
356//function : TransferRoots
357//purpose : Transfers all Roots Entities
358//=======================================================================
359void IGESToBRep_Reader::TransferRoots (const Standard_Boolean onlyvisible)
360{
361 if (theModel.IsNull() || theProc.IsNull()) return;
362
363 Handle(Message_Messenger) TF = theProc->Messenger();
364 // Declaration of messages.
365 Message_Msg msg2030("IGES_2030");
366 TF->Send (msg2030, Message_Info);
367 Message_Msg msg2065("IGES_2065");
368 OSD_Timer c; c.Reset(); c.Start(); // Initialisation du CHRONO
369 theDone = Standard_False;
370 theShapes.Clear();
371
372 Standard_Integer level = theProc->TraceLevel();
373 theProc->SetErrorHandle(Standard_True);
374 theProc->SetRootManagement(Standard_True);
375// PrepareTransfer(); -> protocol, actor
376 theActor->SetModel(theModel);
377 Standard_Integer continuity = Interface_Static::IVal("read.iges.bspline.continuity");
378 theActor->SetContinuity (continuity);
379 theProc->SetModel (theModel);
380 theProc->SetActor (theActor);
381 Transfer_TransferOutput TP (theProc,theModel);
382
383 Interface_ShareFlags SH (theModel,protocol);
384 Standard_Integer nb = theModel->NbEntities();
385 ShapeExtend_Explorer SBE;
386
387
388 Standard_Integer precisionMode = Interface_Static::IVal("read.precision.mode");
389 Message_Msg msg2035("IGES_2035");
390 msg2035.Arg(precisionMode);
391 TF->Send (msg2035, Message_Info);
392 if (precisionMode==1) {
393 Message_Msg msg2040("IGES_2040");
394 msg2040.Arg(Interface_Static::RVal("read.precision.val"));//#70 rln 03.03.99
395 TF->Send (msg2040, Message_Info);
396 }
397 Message_Msg msg2045("IGES_2045");
398 msg2045.Arg(continuity);
399 TF->Send (msg2045, Message_Info);
400 Message_Msg msg2050("IGES_2050");
401 msg2050.Arg(Interface_Static::IVal("read.surfacecurve.mode"));
402 TF->Send (msg2050, Message_Info);
403
404 // sln 11.06.2002 OCC448
405 Interface_Static::SetIVal("read.iges.onlyvisible",onlyvisible);
406
407 Message_ProgressSentry PS ( theProc->GetProgress(), "Root", 0, nb, 1 );
408 for (Standard_Integer i = 1; i <= nb && PS.More(); i++, PS.Next()) {
409 Handle(IGESData_IGESEntity) ent = theModel->Entity(i);
410 if ( SH.IsShared(ent) || ! theActor->Recognize (ent) ) continue;
411 if (level > 0) {
412 Message_Msg msg2070("IGES_2070");
413 msg2070.Arg(2*i-1);
414 msg2070.Arg(ent->TypeNumber());
415 TF->Send (msg2070, Message_Info);
416 }
417 // on ajoute un traitement pour ne prendre que les entites visibles
418 if ( ! onlyvisible || ent->BlankStatus() == 0 ) {
419 TopoDS_Shape shape;
420 theDone = Standard_True;
421 try {
422 OCC_CATCH_SIGNALS
423 TP.Transfer(ent);
424 shape = TransferBRep::ShapeResult (theProc,ent);
425 }
426 catch(Standard_Failure) {
427 Message_Msg msg1005("IGES_1005");
428 TF->Send (msg1005, Message_Info);
429 continue;
430 }
431 if (shape.IsNull()) {
432 Message_Msg msg2076("IGES_2076");
433 TF->Send (msg2076, Message_Info);
434 }
435 else {
436 if (SBE.ShapeType(shape,Standard_True) != TopAbs_SHAPE) {
437 if (!shape.IsNull()) {
438 EncodeRegul (shape);
439 //#74 rln 03.03.99 S4135
440 TrimTolerances (shape, theActor->UsedTolerance());
441 theShapes.Append(shape);
442 }
443 }
444 }
445 }
446 }
447 char t [20];
448 t[0]='\0';
449 Standard_Real second, cpu;
450 Standard_Integer minute, hour;
451 c.Show(second, minute, hour,cpu);
452 if (hour > 0)
453 sprintf(t,"%dh:%dm:%.2fs",hour,minute,second);
454 else if (minute > 0)
455 sprintf(t,"%dm:%.2fs",minute,second);
456 else
457 sprintf(t,"%.2fs",second);
458 // Sending of message : End of Loading
459 msg2065.Arg(t);
460 TF->Send (msg2065, Message_Info);
461}
462
463
464//=======================================================================
465//function : Transfer
466//purpose : Transfers an Entity given
467//=======================================================================
468Standard_Boolean IGESToBRep_Reader::Transfer(const Standard_Integer num)
469{
470 Handle(Message_Messenger) TF = theProc->Messenger();
471 theDone = Standard_False;
472 if (theModel.IsNull()) {
473 Message_Msg msg2031("IGES_2031");
474 TF->Send (msg2031, Message_Info);
475 return Standard_False;
476 }
477 if (num <= 0 || num > theModel->NbEntities()) {
478 Message_Msg msg2032("IGES_2032");
479 msg2032.Arg(num);
480 TF->Send (msg2032, Message_Info);
481 return Standard_False;
482 }
483 // declaration of messages
484 Message_Msg msg2030("IGES_2030");
485 TF->Send (msg2030, Message_Info);
486 Message_Msg msg2065("IGES_2065");
487 OSD_Timer c; c.Reset(); c.Start(); // Initialisation du CHRONO
488
489 Handle(IGESData_IGESEntity) ent = theModel->Entity(num);
490
491 Message_ProgressSentry PS ( theProc->GetProgress(), "OneEnt", 0, 1, 1 ); //skl
492
493 XSAlgo::AlgoContainer()->PrepareForTransfer();
494 IGESToBRep_CurveAndSurface CAS;
495 CAS.SetModel(theModel);
496 Standard_Real eps;
497 Standard_Integer Ival = Interface_Static::IVal("read.precision.mode");
498 Message_Msg msg2035("IGES_2035");
499 msg2035.Arg(Ival);
500 TF->Send (msg2035, Message_Info);
501 if ( Ival == 0)
502 eps = theModel->GlobalSection().Resolution();
503 else {
504 //mjm : modif du 19/12/97 pour prise en compte effective du parametre
505 eps = Interface_Static::RVal("read.precision.val");
506 Message_Msg msg2040("IGES_2040");
507 msg2040.Arg(eps);//#70 rln 03.03.99
508 TF->Send (msg2040, Message_Info);
509
510 }
511 Ival = Interface_Static::IVal("read.iges.bspline.approxd1.mode");
512 CAS.SetModeApprox ( (Ival > 0) );
513 Message_Msg msg2045("IGES_2045");
514 Ival = Interface_Static::IVal("read.iges.bspline.continuity");
515 msg2045.Arg(Ival);
516 TF->Send (msg2045, Message_Info);
517 CAS.SetContinuity(Ival);
518 Message_Msg msg2050("IGES_2050");
519 Ival = Interface_Static::IVal("read.surfacecurve.mode");
520 msg2050.Arg(Ival);
521 TF->Send (msg2050, Message_Info);
522 CAS.SetSurfaceCurve (Ival);
523
524 if (eps > 1.E-08) CAS.SetEpsGeom(eps);
525 CAS.SetTransferProcess(theProc);
526
527 Standard_Boolean exceptionRaised = Standard_False;
528 TopoDS_Shape shape;
529 Standard_Integer nbTPitems = theProc->NbMapped();
530 {
531 try {
532 OCC_CATCH_SIGNALS
533 shape = CAS.TransferGeometry (ent);
534 }
535 catch(Standard_Failure) {
536 Message_Msg msg1015("IGES_1015");
537 TF->Send (msg1015, Message_Info);
538 exceptionRaised = Standard_True;
539 }
540 }
541 if (!exceptionRaised) {
542 // fixing shape
543// shape = XSAlgo::AlgoContainer()->PerformFixShape ( shape, theProc, eps*CAS.GetUnitFactor(), CAS.GetMaxTol() );
544
545 Handle(Standard_Transient) info;
546 shape = XSAlgo::AlgoContainer()->ProcessShape( shape, eps*CAS.GetUnitFactor(), CAS.GetMaxTol(),
547 "read.iges.resource.name",
548 "read.iges.sequence", info );
549 XSAlgo::AlgoContainer()->MergeTransferInfo(theProc, info, nbTPitems);
550
551 ShapeExtend_Explorer SBE;
552 if (SBE.ShapeType (shape,Standard_True) != TopAbs_SHAPE) {
553 TransferBRep::SetShapeResult (theProc,ent,shape);
554 theProc->SetRoot (ent);
555 if (!shape.IsNull()) {
556 theDone = Standard_True;
557 EncodeRegul (shape);
558 //#74 rln 03.03.99 S4135
559 TrimTolerances (shape, CAS.GetMaxTol());
560 theShapes.Append(shape);
561 }
562 }
563 }
564
565 PS.Relieve(); //skl
566
567 char t [20];
568 t[0]='\0';
569 Standard_Real second, cpu;
570 Standard_Integer minute, hour;
571 c.Show(second, minute, hour,cpu);
572 if (hour > 0)
573 sprintf(t,"%dh:%dm:%.2fs",hour,minute,second);
574 else if (minute > 0)
575 sprintf(t,"%dm:%.2fs",minute,second);
576 else
577 sprintf(t,"%.2fs",second);
578 // Sending of message : End of Loading
579 msg2065.Arg(t);
580 TF->Send (msg2065, Message_Info);
581 return Standard_True;
582}
583
584
585//=======================================================================
586//function : UsedTolerance
587//purpose : Returns the used tolerance (input)
588//=======================================================================
589 Standard_Real IGESToBRep_Reader::UsedTolerance () const
590 { return theActor->UsedTolerance(); }
591
592//=======================================================================
593//function : NbShapes
594//purpose : Returns the count of produced Shapes
595//=======================================================================
596 Standard_Integer IGESToBRep_Reader::NbShapes () const
597 { return theShapes.Length(); }
598
599
600//=======================================================================
601//function : Shape
602//purpose : Returns a Shape given its rank
603//=======================================================================
604 TopoDS_Shape IGESToBRep_Reader::Shape (const Standard_Integer num) const
605{
606 TopoDS_Shape res;
607 if (num > 0 && num <= theShapes.Length()) res = theShapes.Value(num);
608 return res;
609}
610
611
612//=======================================================================
613//function : OneShape
614//purpose : Returns a unique Shape
615//=======================================================================
616 TopoDS_Shape IGESToBRep_Reader::OneShape () const
617{
618 TopoDS_Shape res;
619 Standard_Integer nb = theShapes.Length();
620 if (nb == 0) return res;
621 else if (nb == 1) return theShapes.Value(1);
622 else {
623 TopoDS_Compound C;
624 BRep_Builder B;
625 B.MakeCompound(C);
626 for (Standard_Integer i = 1; i <= nb; i ++) B.Add (C,theShapes.Value(i));
627 return C;
628 }
629}