1 // Copyright (c) 1999-2014 OPEN CASCADE SAS
3 // This file is part of Open CASCADE Technology software library.
5 // This library is free software; you can redistribute it and/or modify it under
6 // the terms of the GNU Lesser General Public License version 2.1 as published
7 // by the Free Software Foundation, with special exception defined in the file
8 // OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
9 // distribution for complete text of the license and disclaimer of any warranty.
11 // Alternatively, this file may be used under the terms of Open CASCADE
12 // commercial license or contractual agreement.
14 //pdn 11.01.99 including <stdio.h> for compilation on NT
15 //#70 rln 03.03.99 syntax correction
16 // sln 11.06.2002 OCC448 : Initialize "read.onlyvisiable" parameter to control transfering invisiable sub entities which logicaly depend on the grouping entities
18 #include <IGESToBRep_Reader.ixx>
19 #include <Standard_ErrorHandler.hxx>
20 #include <Standard_Failure.hxx>
21 #include <OSD_Timer.hxx>
23 #include <gp_Trsf.hxx>
26 #include <TopoDS_Compound.hxx>
27 #include <TopoDS_Shape.hxx>
28 #include <BRep_Builder.hxx>
29 #include <BRepLib.hxx>
30 #include <BRepTools_Modifier.hxx>
32 #include <Message_Msg.hxx>
33 #include <Message_Messenger.hxx>
35 #include <IGESFile_Read.hxx>
36 #include <IGESData_FileProtocol.hxx>
37 #include <IGESData_GlobalSection.hxx>
38 #include <IGESData_IGESEntity.hxx>
39 #include <IGESSolid.hxx>
40 #include <IGESSolid_Protocol.hxx>
41 #include <IGESAppli.hxx>
42 #include <IGESAppli_Protocol.hxx>
44 #include <Interface_Macros.hxx>
45 #include <Interface_CheckTool.hxx>
46 #include <Interface_CheckIterator.hxx>
47 #include <Interface_ShareFlags.hxx>
48 #include <Interface_Static.hxx>
49 #include <Interface_Check.hxx>
51 #include <IGESToBRep.hxx>
52 #include <IGESToBRep_Actor.hxx>
53 #include <IGESToBRep_CurveAndSurface.hxx>
55 //#include <ShapeCustom.hxx>
56 #include <ShapeExtend_Explorer.hxx>
57 #include <ShapeFix_ShapeTolerance.hxx>
59 #include <Transfer_TransferOutput.hxx>
60 #include <Transfer_IteratorOfProcessForTransient.hxx>
61 #include <TransferBRep.hxx>
62 #include <TransferBRep_ShapeBinder.hxx>
63 #include <TransferBRep_ShapeListBinder.hxx>
65 #include <XSAlgo_AlgoContainer.hxx>
67 #include <ShapeAlgo.hxx>
68 #include <ShapeAlgo_AlgoContainer.hxx>
69 #include <Message_ProgressSentry.hxx>
78 static Handle(IGESData_FileProtocol) protocol;
81 //=======================================================================
82 //function : IGESToBRep_Reader
84 //=======================================================================
85 IGESToBRep_Reader::IGESToBRep_Reader ()
87 theDone = Standard_False;
88 if (protocol.IsNull()) {
89 IGESAppli::Init(); IGESSolid::Init();
90 protocol = new IGESData_FileProtocol;
91 protocol->Add(IGESAppli::Protocol());
92 protocol->Add(IGESSolid::Protocol());
94 theActor = new IGESToBRep_Actor;
95 theProc = new Transfer_TransientProcess;
99 //=======================================================================
100 //function : LoadFile
101 //purpose : loads a Model from a file
102 //=======================================================================
104 Standard_Integer IGESToBRep_Reader::LoadFile (const Standard_CString filename)
106 if ( theProc.IsNull() )
107 theProc = new Transfer_TransientProcess;
108 Handle(Message_Messenger) TF = theProc->Messenger();
110 // Message for Diagnostic file.
111 Message_Msg msg2000("IGES_2000");
112 msg2000.Arg(filename);
113 TF->Send (msg2000, Message_Info);
114 //Message_Msg msg2001("IGES_2001"); // Date
115 Message_Msg msg2005("IGES_2005");
116 msg2005.Arg(theProc->TraceLevel());
117 TF->Send (msg2005, Message_Info);
118 /////////////////////////////////////////////////////////
119 Handle(IGESData_IGESModel) model = new IGESData_IGESModel;
121 OSD_Timer c; c.Reset(); c.Start();
122 char *pfilename=(char *)filename;
123 Standard_Integer StatusFile = IGESFile_Read(pfilename,model,protocol);
124 if (StatusFile != 0) {
125 // Sending of message : IGES file opening error
126 Message_Msg Msg2("XSTEP_2");
127 TF->Send (Msg2, Message_Info);
128 //Message_Msg Msg3("XSTEP_3");
129 //Message_Msg Msg4("XSTEP_4");
130 //Message_Msg Msg5("XSTEP_5");
131 //Message_Msg Msg6("XSTEP_6");
132 //Message_Msg Msg7("XSTEP_7");
133 // Reasons of the file opening error
136 case 2 : // Sending of message : No such file or directory
138 Message_Msg Msg3("XSTEP_3");
139 TF->Send (Msg3, Message_Info);
142 case 12 : // Sending of message : Not enough space
144 Message_Msg Msg4("XSTEP_4");
145 TF->Send (Msg4, Message_Info);
148 case 13 : // Sending of message : Permission Denied
150 Message_Msg Msg5("XSTEP_5");
151 TF->Send (Msg5, Message_Info);
154 case 24 : // Sending of message : Too many open files
156 Message_Msg Msg6("XSTEP_6");
157 TF->Send (Msg6, Message_Info);
160 default : // Sending of message : No determined
162 Message_Msg Msg7("XSTEP_7");
163 TF->Send (Msg7, Message_Info);
169 Message_Msg Msg8 ("XSTEP_8");
170 Message_Msg Msg25 ("XSTEP_25");
171 Message_Msg Msg26 ("XSTEP_26");
172 // Nb warning in global section.
174 Standard_Integer nbWarn = 0,nbFail = 0;
175 // Add the number of warning on enities :
176 Interface_CheckTool cht (model,protocol);
177 Interface_CheckIterator anIter = cht.CompleteCheckList();
178 for(anIter.Start(); anIter.More(); anIter.Next()) {
179 const Handle(Interface_Check) ach = anIter.Value();
180 nbWarn += ach->NbWarnings();
181 nbFail += ach->NbFails();
183 // Messages nbWarn and nbFail;
186 TF->Send (Msg25, Message_Info);
187 TF->Send (Msg26, Message_Info);
189 // Message fin de loading iGES file (elapsed time %s)
192 Standard_Real second, cpu;
193 Standard_Integer minute, hour;
194 c.Show(second, minute, hour,cpu);
196 Sprintf(t,"%dh:%dm:%.2fs",hour,minute,second);
198 Sprintf(t,"%dm:%.2fs",minute,second);
200 Sprintf(t,"%.2fs",second);
201 // Sending of message : End of Loading
203 TF->Send (Msg8, Message_Info);
210 //=======================================================================
211 //function : SetModel
212 //purpose : Specifies a Model to work on
213 //=======================================================================
214 void IGESToBRep_Reader::SetModel (const Handle(IGESData_IGESModel)& model)
217 theDone = Standard_False;
219 if ( theProc.IsNull() )
220 theProc = new Transfer_TransientProcess (theModel->NbEntities());
226 //=======================================================================
228 //purpose : returns the Model to be worked on
229 //=======================================================================
230 Handle(IGESData_IGESModel) IGESToBRep_Reader::Model () const
234 //=======================================================================
235 //function : SetTransientProcess
236 //purpose : Specifies a TransferProcess
237 //=======================================================================
238 void IGESToBRep_Reader::SetTransientProcess
239 (const Handle(Transfer_TransientProcess)& TP)
242 //=======================================================================
243 //function : TransientProcess
244 //purpose : Returns the TransferProcess
245 //=======================================================================
246 Handle(Transfer_TransientProcess) IGESToBRep_Reader::TransientProcess () const
249 //=======================================================================
251 //purpose : returns theActor
252 //=======================================================================
253 Handle(IGESToBRep_Actor) IGESToBRep_Reader::Actor () const
257 //=======================================================================
259 //purpose : Clears the result and Done status
260 //=======================================================================
261 void IGESToBRep_Reader::Clear ()
263 theDone = Standard_False;
268 //=======================================================================
270 //purpose : Checks the Model
271 //=======================================================================
272 Standard_Boolean IGESToBRep_Reader::Check
273 (const Standard_Boolean withprint) const
275 Interface_CheckTool cht (theModel,protocol);
276 Interface_CheckIterator chl = cht.CompleteCheckList();
277 if (withprint && !theProc.IsNull())
278 cht.Print(chl, theProc->Messenger());
279 return chl.IsEmpty(Standard_True);
283 //=======================================================================
285 //purpose : returns True if the last transfert was a success
286 //=======================================================================
287 Standard_Boolean IGESToBRep_Reader::IsDone () const
291 //=======================================================================
292 //function : EncodeRegul
293 //purpose : INTERNAL to encode regularity on edges
294 //=======================================================================
296 static Standard_Boolean EncodeRegul (const TopoDS_Shape& sh)
298 Standard_Real tolang = Interface_Static::RVal("read.encoderegularity.angle");
299 if (sh.IsNull()) return Standard_True;
300 if (tolang <= 0) return Standard_True;
303 BRepLib::EncodeRegularity (sh,tolang);
305 catch(Standard_Failure) {
306 return Standard_False;
308 return Standard_True;
311 //=======================================================================
312 //function : UpdateMap
313 //purpose : Updates the correspondence map (Transfer_TransientProcess),
314 // setting as translation results, the shapes received after
315 // modification by modifier (BRepTools_Modifier)
316 //warning : BRepTools_Modifier raises exception when it cannot find input
317 // shape in its internal list
318 //=======================================================================
320 // coment as unused PTV 18.09.2000
321 // static void UpdateMap (const Handle(Transfer_TransientProcess)& map,
322 // const BRepTools_Modifier& modifier)
324 // Transfer_IteratorOfProcessForTransient iterator = map->CompleteResult(Standard_True);
325 // for (iterator.Start(); iterator.More(); iterator.Next()) {
326 // const Handle(Transfer_Binder) binder = iterator.Value();
327 // try { //to avoid exception in BRepTools_Modifier
329 // if (binder->IsKind (STANDARD_TYPE (TransferBRep_ShapeBinder))) {
330 // DeclareAndCast(TransferBRep_ShapeBinder, shapebinder, binder);
331 // if (shapebinder->HasResult()) {
332 // TopoDS_Shape result = shapebinder->Result();
333 // TopoDS_Shape modified = modifier.ModifiedShape (result);
334 // if (shapebinder->Status() != Transfer_StatusUsed) //to avoid exception
335 // shapebinder->SetResult (modified);
338 // else if (binder->IsKind (STANDARD_TYPE (TransferBRep_ShapeListBinder))) {
339 // DeclareAndCast(TransferBRep_ShapeListBinder, shapelistbinder, binder);
340 // for (Standard_Integer i = 1; i <= shapelistbinder->NbShapes(); i++) {
341 // TopoDS_Shape result = shapelistbinder->Shape (i);
342 // TopoDS_Shape modified = modifier.ModifiedShape (result);
343 // shapelistbinder->SetResult (i, modified);
347 // catch(Standard_Failure) {
353 //=======================================================================
354 //function : TrimTolerances
355 //purpose : Trims tolerances of the shape according to static parameters
357 //=======================================================================
359 static void TrimTolerances (const TopoDS_Shape& shape,
360 const Standard_Real tol)
362 if( Interface_Static::IVal("read.maxprecision.mode")==1) {
363 ShapeFix_ShapeTolerance SFST;
364 SFST.LimitTolerance (shape, 0, Max(tol,Interface_Static::RVal ("read.maxprecision.val")));
368 //=======================================================================
369 //function : TransferRoots
370 //purpose : Transfers all Roots Entities
371 //=======================================================================
372 void IGESToBRep_Reader::TransferRoots (const Standard_Boolean onlyvisible)
374 if (theModel.IsNull() || theProc.IsNull()) return;
376 Handle(Message_Messenger) TF = theProc->Messenger();
377 // Declaration of messages.
378 Message_Msg msg2030("IGES_2030");
379 TF->Send (msg2030, Message_Info);
380 Message_Msg msg2065("IGES_2065");
381 OSD_Timer c; c.Reset(); c.Start(); // Initialisation du CHRONO
382 theDone = Standard_False;
385 Standard_Integer level = theProc->TraceLevel();
386 theProc->SetErrorHandle(Standard_True);
387 theProc->SetRootManagement(Standard_True);
388 // PrepareTransfer(); -> protocol, actor
389 theActor->SetModel(theModel);
390 Standard_Integer continuity = Interface_Static::IVal("read.iges.bspline.continuity");
391 theActor->SetContinuity (continuity);
392 theProc->SetModel (theModel);
393 theProc->SetActor (theActor);
394 Transfer_TransferOutput TP (theProc,theModel);
396 Interface_ShareFlags SH (theModel,protocol);
397 Standard_Integer nb = theModel->NbEntities();
398 ShapeExtend_Explorer SBE;
401 Standard_Integer precisionMode = Interface_Static::IVal("read.precision.mode");
402 Message_Msg msg2035("IGES_2035");
403 msg2035.Arg(precisionMode);
404 TF->Send (msg2035, Message_Info);
405 if (precisionMode==1) {
406 Message_Msg msg2040("IGES_2040");
407 msg2040.Arg(Interface_Static::RVal("read.precision.val"));//#70 rln 03.03.99
408 TF->Send (msg2040, Message_Info);
410 Message_Msg msg2045("IGES_2045");
411 msg2045.Arg(continuity);
412 TF->Send (msg2045, Message_Info);
413 Message_Msg msg2050("IGES_2050");
414 msg2050.Arg(Interface_Static::IVal("read.surfacecurve.mode"));
415 TF->Send (msg2050, Message_Info);
417 // sln 11.06.2002 OCC448
418 Interface_Static::SetIVal("read.iges.onlyvisible",onlyvisible);
420 Message_ProgressSentry PS ( theProc->GetProgress(), "Root", 0, nb, 1 );
421 for (Standard_Integer i = 1; i <= nb && PS.More(); i++, PS.Next()) {
422 Handle(IGESData_IGESEntity) ent = theModel->Entity(i);
423 if ( SH.IsShared(ent) || ! theActor->Recognize (ent) ) continue;
425 Message_Msg msg2070("IGES_2070");
427 msg2070.Arg(ent->TypeNumber());
428 TF->Send (msg2070, Message_Info);
430 // on ajoute un traitement pour ne prendre que les entites visibles
431 if ( ! onlyvisible || ent->BlankStatus() == 0 ) {
433 theDone = Standard_True;
437 shape = TransferBRep::ShapeResult (theProc,ent);
439 catch(Standard_Failure) {
440 Message_Msg msg1005("IGES_1005");
441 TF->Send (msg1005, Message_Info);
444 if (shape.IsNull()) {
445 Message_Msg msg2076("IGES_2076");
446 TF->Send (msg2076, Message_Info);
449 if (SBE.ShapeType(shape,Standard_True) != TopAbs_SHAPE) {
450 if (!shape.IsNull()) {
452 //#74 rln 03.03.99 S4135
453 TrimTolerances (shape, theActor->UsedTolerance());
454 theShapes.Append(shape);
462 Standard_Real second, cpu;
463 Standard_Integer minute, hour;
464 c.Show(second, minute, hour,cpu);
466 Sprintf(t,"%dh:%dm:%.2fs",hour,minute,second);
468 Sprintf(t,"%dm:%.2fs",minute,second);
470 Sprintf(t,"%.2fs",second);
471 // Sending of message : End of Loading
473 TF->Send (msg2065, Message_Info);
477 //=======================================================================
478 //function : Transfer
479 //purpose : Transfers an Entity given
480 //=======================================================================
481 Standard_Boolean IGESToBRep_Reader::Transfer(const Standard_Integer num)
483 Handle(Message_Messenger) TF = theProc->Messenger();
484 theDone = Standard_False;
485 if (theModel.IsNull()) {
486 Message_Msg msg2031("IGES_2031");
487 TF->Send (msg2031, Message_Info);
488 return Standard_False;
490 if (num <= 0 || num > theModel->NbEntities()) {
491 Message_Msg msg2032("IGES_2032");
493 TF->Send (msg2032, Message_Info);
494 return Standard_False;
496 // declaration of messages
497 Message_Msg msg2030("IGES_2030");
498 TF->Send (msg2030, Message_Info);
499 Message_Msg msg2065("IGES_2065");
500 OSD_Timer c; c.Reset(); c.Start(); // Initialisation du CHRONO
502 Handle(IGESData_IGESEntity) ent = theModel->Entity(num);
504 Message_ProgressSentry PS ( theProc->GetProgress(), "OneEnt", 0, 1, 1 ); //skl
506 XSAlgo::AlgoContainer()->PrepareForTransfer();
507 IGESToBRep_CurveAndSurface CAS;
508 CAS.SetModel(theModel);
510 Standard_Integer Ival = Interface_Static::IVal("read.precision.mode");
511 Message_Msg msg2035("IGES_2035");
513 TF->Send (msg2035, Message_Info);
515 eps = theModel->GlobalSection().Resolution();
517 //mjm : modif du 19/12/97 pour prise en compte effective du parametre
518 eps = Interface_Static::RVal("read.precision.val");
519 Message_Msg msg2040("IGES_2040");
520 msg2040.Arg(eps);//#70 rln 03.03.99
521 TF->Send (msg2040, Message_Info);
524 Ival = Interface_Static::IVal("read.iges.bspline.approxd1.mode");
525 CAS.SetModeApprox ( (Ival > 0) );
526 Message_Msg msg2045("IGES_2045");
527 Ival = Interface_Static::IVal("read.iges.bspline.continuity");
529 TF->Send (msg2045, Message_Info);
530 CAS.SetContinuity(Ival);
531 Message_Msg msg2050("IGES_2050");
532 Ival = Interface_Static::IVal("read.surfacecurve.mode");
534 TF->Send (msg2050, Message_Info);
535 CAS.SetSurfaceCurve (Ival);
537 if (eps > 1.E-08) CAS.SetEpsGeom(eps);
538 CAS.SetTransferProcess(theProc);
540 Standard_Boolean exceptionRaised = Standard_False;
542 Standard_Integer nbTPitems = theProc->NbMapped();
546 shape = CAS.TransferGeometry (ent);
548 catch(Standard_Failure) {
549 Message_Msg msg1015("IGES_1015");
550 TF->Send (msg1015, Message_Info);
551 exceptionRaised = Standard_True;
554 if (!exceptionRaised) {
556 // shape = XSAlgo::AlgoContainer()->PerformFixShape ( shape, theProc, eps*CAS.GetUnitFactor(), CAS.GetMaxTol() );
558 Handle(Standard_Transient) info;
559 shape = XSAlgo::AlgoContainer()->ProcessShape( shape, eps*CAS.GetUnitFactor(), CAS.GetMaxTol(),
560 "read.iges.resource.name",
561 "read.iges.sequence", info,
562 theProc->GetProgress() );
563 XSAlgo::AlgoContainer()->MergeTransferInfo(theProc, info, nbTPitems);
565 ShapeExtend_Explorer SBE;
566 if (SBE.ShapeType (shape,Standard_True) != TopAbs_SHAPE) {
567 TransferBRep::SetShapeResult (theProc,ent,shape);
568 theProc->SetRoot (ent);
569 if (!shape.IsNull()) {
570 theDone = Standard_True;
572 //#74 rln 03.03.99 S4135
573 TrimTolerances (shape, CAS.GetMaxTol());
574 theShapes.Append(shape);
583 Standard_Real second, cpu;
584 Standard_Integer minute, hour;
585 c.Show(second, minute, hour,cpu);
587 Sprintf(t,"%dh:%dm:%.2fs",hour,minute,second);
589 Sprintf(t,"%dm:%.2fs",minute,second);
591 Sprintf(t,"%.2fs",second);
592 // Sending of message : End of Loading
594 TF->Send (msg2065, Message_Info);
595 return Standard_True;
599 //=======================================================================
600 //function : UsedTolerance
601 //purpose : Returns the used tolerance (input)
602 //=======================================================================
603 Standard_Real IGESToBRep_Reader::UsedTolerance () const
604 { return theActor->UsedTolerance(); }
606 //=======================================================================
607 //function : NbShapes
608 //purpose : Returns the count of produced Shapes
609 //=======================================================================
610 Standard_Integer IGESToBRep_Reader::NbShapes () const
611 { return theShapes.Length(); }
614 //=======================================================================
616 //purpose : Returns a Shape given its rank
617 //=======================================================================
618 TopoDS_Shape IGESToBRep_Reader::Shape (const Standard_Integer num) const
621 if (num > 0 && num <= theShapes.Length()) res = theShapes.Value(num);
626 //=======================================================================
627 //function : OneShape
628 //purpose : Returns a unique Shape
629 //=======================================================================
630 TopoDS_Shape IGESToBRep_Reader::OneShape () const
633 Standard_Integer nb = theShapes.Length();
634 if (nb == 0) return res;
635 else if (nb == 1) return theShapes.Value(1);
640 for (Standard_Integer i = 1; i <= nb; i ++) B.Add (C,theShapes.Value(i));