4bcc76d3033c39cbdb0f029592b3f073d93b53f8
[occt.git] / src / IGESToBRep / IGESToBRep_CurveAndSurface.cxx
1 // Copyright (c) 1999-2014 OPEN CASCADE SAS
2 //
3 // This file is part of Open CASCADE Technology software library.
4 //
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.
10 //
11 // Alternatively, this file may be used under the terms of Open CASCADE
12 // commercial license or contractual agreement.
13
14 // 22.12.98 dce S3767
15 // 21.12.98 rln, gka S4054
16 //#74 rln,pdn 11.03.99 S4135: Setting minimum and maximum tolerances according to static parameters
17 // sln 13.06.2002 OCC448 : Correction in  method TransferGeometry to avoid transfering invisiable sub entities
18
19 #include <Standard_ErrorHandler.hxx>
20 #include <IGESToBRep_CurveAndSurface.ixx>
21 #include <Standard_Failure.hxx>
22
23 #include <IGESToBRep.hxx>
24 #include <IGESToBRep_TopoCurve.hxx>
25 #include <IGESToBRep_TopoSurface.hxx>
26 #include <IGESToBRep_BRepEntity.hxx>
27
28 #include <IGESBasic_Group.hxx>
29 #include <IGESBasic_GroupWithoutBackP.hxx>
30
31 #include <IGESBasic_SubfigureDef.hxx>
32 #include <IGESBasic_SingularSubfigure.hxx>
33
34 #include <IGESData_ToolLocation.hxx>
35
36 #include <BRep_Builder.hxx>
37
38 #include <BRepLib.hxx>
39
40 #include <gp_Trsf.hxx>
41 #include <gp_GTrsf.hxx>
42 #include <gp_Vec.hxx>
43 #include <Precision.hxx>
44
45 #include <Interface_Macros.hxx>
46 #include <Interface_Static.hxx>
47
48 #include <TopExp_Explorer.hxx>
49 #include <TopLoc_Location.hxx>
50 #include <TopoDS.hxx>
51 #include <TopoDS_Compound.hxx>
52 #include <TopoDS_Edge.hxx>
53 #include <TopoDS_Shape.hxx>
54
55 #include <Transfer_TransientProcess.hxx>
56 #include <TransferBRep_ShapeBinder.hxx>
57 #include <TransferBRep_ShapeListBinder.hxx>
58 #include <stdio.h>
59
60 #include <Message_Msg.hxx>
61 #include <Message_Messenger.hxx>
62 #include <Message_ProgressSentry.hxx>
63 #include <GeomAdaptor_Surface.hxx>
64
65 //=======================================================================
66 //function : IGESToBRep_CurveAndSurface
67 //purpose  : 
68 //=======================================================================
69
70 IGESToBRep_CurveAndSurface::IGESToBRep_CurveAndSurface()
71 {
72   Init();
73 }
74
75
76 //=======================================================================
77 //function : IGESToBRep_CurveAndSurface
78 //purpose  : 
79 //=======================================================================
80
81 IGESToBRep_CurveAndSurface::IGESToBRep_CurveAndSurface
82   (const IGESToBRep_CurveAndSurface& other)
83 {  
84   myEps        = other.GetEpsilon();
85   myEpsCoeff   = other.GetEpsCoeff();
86   myEpsGeom    = other.GetEpsGeom();
87   myMaxTol     = other.GetMaxTol();
88   myModeIsTopo = other.GetModeTransfer();
89   myModeApprox = other.GetModeApprox();
90   myContIsOpti = other.GetOptimized();
91   myUnitFactor = other.GetUnitFactor();
92   mySurfaceCurve = other.GetSurfaceCurve();
93   myContinuity = other.GetContinuity();
94   myModel      = other.GetModel();
95   myTP         = other.GetTransferProcess();
96   myMinTol     = other.GetMinTol();
97   
98   mySurface = other.Surface();
99   myIsResolCom = other.myIsResolCom;
100   myUVResolution = other.myUVResolution;
101 }
102
103
104 //=======================================================================
105 //function : IGESToBRep_CurveAndSurface
106 //purpose  : 
107 //=======================================================================
108
109 IGESToBRep_CurveAndSurface::IGESToBRep_CurveAndSurface
110   (const Standard_Real    eps,
111    const Standard_Real    epsCoeff,
112    const Standard_Real    epsGeom,
113    const Standard_Boolean mode,
114    const Standard_Boolean modeapprox,
115    const Standard_Boolean optimized)
116 {  
117   myEps        = eps;
118   myEpsCoeff   = epsCoeff;
119   myEpsGeom    = epsGeom;
120   myModeIsTopo = mode;
121   myModeApprox = modeapprox;
122   myContIsOpti = optimized;
123   myUnitFactor = 1.;
124   mySurfaceCurve = 0;
125   myContinuity = 0;
126   myTP         = new Transfer_TransientProcess();
127   
128   myIsResolCom = Standard_False;
129   myUVResolution = 0.;
130   UpdateMinMaxTol();
131 }
132
133 //=======================================================================
134 //function : Init
135 //purpose  : 
136 //=======================================================================
137
138 void IGESToBRep_CurveAndSurface::Init()
139 {  
140   myEps        = 1.E-04;
141   myEpsCoeff   = 1.E-06;
142   myEpsGeom    = 1.E-04;
143   myModeIsTopo = Standard_True;
144   myModeApprox = Standard_False;
145   myContIsOpti = Standard_False;
146   myUnitFactor = 1.;
147   mySurfaceCurve = 0;
148   myContinuity = 0;
149   myTP         = new Transfer_TransientProcess();
150   
151   mySurface.Nullify();
152   myIsResolCom = Standard_False;
153   myUVResolution = 0.;
154   UpdateMinMaxTol();
155 }
156
157 //=======================================================================
158 //function : SetEpsGeom
159 //purpose  : 
160 //=======================================================================
161 void IGESToBRep_CurveAndSurface::SetEpsGeom(const Standard_Real eps)
162 {
163   myEpsGeom = eps;
164   UpdateMinMaxTol();
165 }
166
167
168 //=======================================================================
169 //function : UpdateMinMaxTol
170 //purpose  : 
171 //=======================================================================
172
173 void IGESToBRep_CurveAndSurface::UpdateMinMaxTol()
174 {
175   //#74 rln 11.03.99 S4135: Setting maximum tolerances according to
176   //static parameter
177   myMaxTol = Max (Interface_Static::RVal ("read.maxprecision.val"), myEpsGeom * myUnitFactor);
178   myMinTol = Precision::Confusion();
179 }
180
181 //=======================================================================
182 //function : SetModel
183 //purpose  : 
184 //=======================================================================
185 void IGESToBRep_CurveAndSurface::SetModel(const Handle(IGESData_IGESModel)& model)
186 {  
187   myModel = model;  
188   Standard_Real unitfactor = myModel->GlobalSection().UnitValue();
189   if (unitfactor != 1.)
190     {
191       if ( myTP->TraceLevel() > 2 )
192         myTP->Messenger() << "UnitFactor = "<< unitfactor << endl;
193       myUnitFactor = unitfactor;
194     }
195   UpdateMinMaxTol();
196 }
197
198 //=======================================================================
199 //function : TransferCurveAndSurface
200 //purpose  : 
201 //=======================================================================
202
203 TopoDS_Shape IGESToBRep_CurveAndSurface::TransferCurveAndSurface
204        (const Handle(IGESData_IGESEntity)& start)
205 {
206   TopoDS_Shape res;
207   if (start.IsNull()) {
208     Message_Msg msg1005("IGES_1005");
209     SendFail(start, msg1005);
210     return res;
211   }
212   Handle(TCollection_HAsciiString) label = GetModel()->StringLabel(start);
213 //  Standard_Integer typeNumber = start->TypeNumber();
214   
215   if (IGESToBRep::IsTopoCurve(start)) {
216     IGESToBRep_TopoCurve TC(*this);
217     res = TC.TransferTopoCurve(start);
218   }  
219   else if (IGESToBRep::IsTopoSurface(start)) {
220     IGESToBRep_TopoSurface TS(*this);
221     res = TS.TransferTopoSurface(start);
222   }
223   else if (IGESToBRep::IsBRepEntity(start)) {
224     IGESToBRep_BRepEntity TS(*this);
225     res = TS.TransferBRepEntity(start);
226   }
227   else {
228     Message_Msg msg1015("IGES_1015");
229     SendFail(start, msg1015);
230     // AddFail(start, "The IGESEntity is not a curve a Surface or a BRep Entity.");
231   }
232   // mjm le 12/09/96
233 /*
234   if (!res.IsNull()) {
235     try {
236       OCC_CATCH_SIGNALS
237       Standard_Real Eps = GetEpsGeom()*GetUnitFactor();
238       BRepLib::SameParameter(res,Eps);
239     }
240     catch(Standard_Failure) {
241     Message_Msg msg1010("IGES_1010");
242       SendWarning (start,msg1010);
243     }
244   }
245 */
246   return res;
247 }
248
249
250
251 //=======================================================================
252 //function : TransferGeometry
253 //purpose  : 
254 //=======================================================================
255
256 TopoDS_Shape IGESToBRep_CurveAndSurface::TransferGeometry
257                                (const Handle(IGESData_IGESEntity)& start)
258 {
259   // Declaration of messages// 
260   // DCE 22/12/98
261   //Message_Msg msg1005("IGES_1005");  //  Software error :  start IsNull.
262   //Message_Msg msg1015("IGES_1015");  //  invalid type or execption raising (software error).
263   //Message_Msg msg1010("IGES_1010");  //  Not sameparameter.
264   //  Message_Msg msg1015("IGES_1015");
265   //Message_Msg msg210 ("XSTEP_210");  
266   //Message_Msg msg202 ("XSTEP_202");
267   ////////////////////////////
268   TopoDS_Shape res;
269   gp_Trsf T408;
270   if (start.IsNull()) {
271     Message_Msg msg1005("IGES_1005");  //  Software error :  start IsNull.
272     SendFail(start, msg1005);
273     return res;
274   }
275
276   // Read of the DE number and the type number of the entity
277   Handle(TCollection_HAsciiString) label = GetModel()->StringLabel(start);
278   //Standard_Integer typeNumber = start->TypeNumber();
279   
280   // sln 13.06.2002 OCC448: Avoid transfering invisiable sub entities which
281   // logicaly depend on the one
282   Standard_Integer onlyvisible = Interface_Static::IVal("read.iges.onlyvisible");
283   
284   if (IGESToBRep::IsCurveAndSurface(start)) {
285     if(onlyvisible && start->BlankStatus() == 1)
286       return res;
287     try {
288       OCC_CATCH_SIGNALS
289         res = TransferCurveAndSurface(start);
290     }
291     catch(Standard_Failure) {
292       Message_Msg msg1015("IGES_1015");
293       SendFail(start, msg1015);
294     }
295     return res;
296   }
297
298   //408 : SingularSubfigure
299   if (start->IsKind(STANDARD_TYPE(IGESBasic_SingularSubfigure))) 
300     {
301       if(onlyvisible && start->BlankStatus() == 1)
302         return res;
303         
304       DeclareAndCast(IGESBasic_SingularSubfigure, st408, start);
305       Handle (IGESBasic_SubfigureDef) stsub = st408->Subfigure();
306       gp_XYZ trans = st408->Translation();
307       gp_Vec vectr(trans);
308       Standard_Real scunit = GetUnitFactor();
309       vectr.Multiply(scunit);
310       T408.SetTranslation(vectr);
311       if (st408->HasScaleFactor()) {
312           Standard_Real scalef = st408->ScaleFactor();
313           T408.SetScaleFactor(scalef);
314         }
315       if (HasShapeResult(stsub)) {
316         res = GetShapeResult(stsub);
317       }
318       else {
319         try {
320           OCC_CATCH_SIGNALS
321           res = TransferGeometry(stsub);
322         }
323         catch(Standard_Failure) {
324           res.Nullify();
325           Message_Msg msg1015("IGES_1015");
326           SendFail( st408, msg1015);
327         }
328         if (!res.IsNull()) {
329           SetShapeResult(stsub,res);
330         }
331       }
332     }
333   
334   // 308 : SubfigureDefinition
335   else if (start->IsKind(STANDARD_TYPE(IGESBasic_SubfigureDef))) {
336     DeclareAndCast(IGESBasic_SubfigureDef, st308, start);
337     TopoDS_Compound group;
338     BRep_Builder B;
339     B.MakeCompound (group);
340     if (st308->NbEntities() < 1) {
341       Message_Msg msg210 ("XSTEP_210");  
342       SendFail( st308, msg210);
343       return res;
344     }
345     Message_ProgressSentry PS ( myTP->GetProgress(), "Subfigure item", 0, st308->NbEntities(), 1 );
346     for (Standard_Integer i=1; i <= st308->NbEntities() && PS.More(); i++, PS.Next()) {
347       TopoDS_Shape item;
348       if (st308->AssociatedEntity(i).IsNull()) {
349         Message_Msg msg1020("IGES_1020");
350         msg1020.Arg(i);
351         SendWarning( st308, msg1020);
352         continue;
353       }
354       if(onlyvisible && st308->AssociatedEntity(i)->BlankStatus() == 1 )
355         continue;      
356         
357       if (HasShapeResult(st308->AssociatedEntity(i)))
358         {
359           item = GetShapeResult(st308->AssociatedEntity(i));
360         }
361       else {
362         try {      
363           OCC_CATCH_SIGNALS
364           item = TransferGeometry(st308->AssociatedEntity(i));
365         }
366         catch(Standard_Failure) {
367           item.Nullify();
368           Message_Msg msg1015("IGES_1015");
369           SendFail( st308->AssociatedEntity(i), msg1015);
370         }
371       }
372       if (item.IsNull()) {
373         Message_Msg msg1025("IGES_1025");
374         msg1025.Arg(i);
375         SendWarning (start,msg1025);
376       }
377       else {
378         B.Add(group, item);
379         SetShapeResult (st308->AssociatedEntity(i),item);
380       }
381     }
382     res = group;
383   }
384   else if (start->IsKind(STANDARD_TYPE(IGESBasic_Group))) {
385     if(onlyvisible && start->BlankStatus() == 1)
386       return res;      
387     
388     DeclareAndCast(IGESBasic_Group, st402f1, start);
389     TopoDS_Compound group;
390     BRep_Builder B;
391     B.MakeCompound (group);
392     if (st402f1->NbEntities() < 1) {
393       Message_Msg msg202 ("XSTEP_202");
394       msg202.Arg(st402f1->FormNumber());
395       SendFail(st402f1, msg202);
396       return res;
397     }
398     Message_ProgressSentry PS ( myTP->GetProgress(), "Group item", 0, st402f1->NbEntities(), 1 );
399     Standard_Boolean ProblemInGroup = Standard_False;
400     for (Standard_Integer i=1; i <= st402f1->NbEntities() && PS.More(); i++, PS.Next()) {
401       TopoDS_Shape item;
402       if (st402f1->Entity(i).IsNull()) {
403         Message_Msg msg1020("IGES_1020");
404         msg1020.Arg(i);
405         SendFail( st402f1, msg1020);
406         continue;
407       }
408       
409       if(onlyvisible && st402f1->Entity(i)->BlankStatus() == 1)
410         continue;      
411       
412       if (HasShapeResult(st402f1->Entity(i))) {
413         item = GetShapeResult(st402f1->Entity(i));
414       }
415       else {
416         try {
417           OCC_CATCH_SIGNALS
418           item = TransferGeometry(st402f1->Entity(i));
419         }
420         catch(Standard_Failure) {
421           item.Nullify();
422           Message_Msg msg1015("IGES_1015");
423           SendFail(st402f1->Entity(i),msg1015);
424         }
425       }
426       if (item.IsNull()) {
427         //Message_Msg msg1030("IGES_1030");
428         //msg1030.Arg(st402f1->FormNumber());
429         //msg1030.Arg(i);
430         //SendWarning (st402f1,msg1030);
431         ProblemInGroup = Standard_True;
432       }
433       else {
434         B.Add(group, item);
435         SetShapeResult (st402f1->Entity(i),item);
436       }
437     }
438     res = group;
439     if(ProblemInGroup) {
440       Message_Msg msg1030("IGES_1030");
441       msg1030.Arg(st402f1->FormNumber());
442       SendWarning (st402f1,msg1030);
443     }
444   }
445   else if (start->IsKind(STANDARD_TYPE(IGESBasic_GroupWithoutBackP))) { 
446     
447     if(onlyvisible && start->BlankStatus() == 1)
448       return res;      
449     
450     DeclareAndCast(IGESBasic_GroupWithoutBackP, st402f7, start);
451     TopoDS_Compound group;
452 //unused    Handle(TCollection_HAsciiString) label = GetModel()->StringLabel(st402f7);
453     BRep_Builder B;
454     B.MakeCompound (group);
455     if (st402f7->NbEntities() < 1) {
456       Message_Msg msg202 ("XSTEP_202");
457       msg202.Arg(st402f7->FormNumber());
458       SendFail(st402f7, msg202); 
459       return res;
460     }
461     Message_ProgressSentry PS ( myTP->GetProgress(), "Group item", 0, st402f7->NbEntities(), 1 );
462     Standard_Boolean ProblemInGroup = Standard_False;
463     for (Standard_Integer i=1; i <= st402f7->NbEntities() && PS.More(); i++, PS.Next()) {
464       TopoDS_Shape item;
465       if (st402f7->Entity(i).IsNull()) {
466         Message_Msg msg1020("IGES_1020");
467         msg1020.Arg(i);
468         SendFail( st402f7, msg1020);
469         continue;
470       }
471       
472       if(onlyvisible && st402f7->Entity(i)->BlankStatus() == 1 )
473         continue;      
474
475       if (HasShapeResult(st402f7->Entity(i))) {
476         item = GetShapeResult(st402f7->Entity(i));
477       }
478       else {
479         try {
480           OCC_CATCH_SIGNALS
481           item = TransferGeometry(st402f7->Entity(i));
482         }
483         catch(Standard_Failure) {
484           item.Nullify();
485           Message_Msg msg1015("IGES_1015");
486           SendFail(st402f7->Entity(i),msg1015);
487         }
488       }
489       if (item.IsNull()) {
490         //Message_Msg msg1030("IGES_1030");
491         //msg1030.Arg(st402f7->FormNumber());
492         //msg1030.Arg(i);
493         //SendWarning (st402f7,msg1030);
494         ProblemInGroup = Standard_True;
495       }
496       else {
497         B.Add(group, item);
498         SetShapeResult (st402f7->Entity(i),item);
499       }
500     }
501     res = group;
502     if(ProblemInGroup) {
503       Message_Msg msg1030("IGES_1030");
504       msg1030.Arg(st402f7->FormNumber());
505       SendWarning (st402f7,msg1030);
506     }
507   }
508   else {
509     Message_Msg msg1001("IGES_1001");
510     msg1001.Arg(start->FormNumber());
511     SendFail (start,msg1001);
512     return res;
513   }
514   
515   if (start->HasTransf()) {
516     gp_Trsf T;
517     SetEpsilon(1.E-04);
518     if (IGESData_ToolLocation::ConvertLocation(GetEpsilon(),start->CompoundLocation(),
519                                                T,GetUnitFactor())) {
520       if (start->IsKind(STANDARD_TYPE(IGESBasic_SingularSubfigure))) 
521         {
522           gp_XYZ tra = T.TranslationPart();
523           gp_XYZ trans = T408.TranslationPart();
524           tra.Add(trans);
525           T.SetTranslationPart(tra);
526           Standard_Real sc = T.ScaleFactor();
527           Standard_Real scalef = T408.ScaleFactor();
528           sc = sc*scalef;
529           T.SetScaleFactor(sc);
530         }
531       TopLoc_Location L(T);
532       res.Move(L);
533     }
534     else {
535       Message_Msg msg1035("IGES_1035");
536       SendWarning (start,msg1035);
537     }
538   }
539   else {
540     if (start->IsKind(STANDARD_TYPE(IGESBasic_SingularSubfigure))) {
541       TopLoc_Location L(T408);
542       res.Move(L);        
543     }
544   }  
545   return res;
546 }
547
548
549 //=======================================================================
550 //function : HasShapeResult
551 //purpose  : 
552 //=======================================================================
553
554 Standard_Boolean IGESToBRep_CurveAndSurface::HasShapeResult 
555   (const Handle(IGESData_IGESEntity)& start) const
556 {
557   DeclareAndCast(TransferBRep_ShapeBinder,binder,myTP->Find(start));
558   if (binder.IsNull()) return Standard_False;
559   return binder->HasResult();
560 }
561
562
563 //=======================================================================
564 //function : GetShapeResult
565 //purpose  : 
566 //=======================================================================
567
568 TopoDS_Shape IGESToBRep_CurveAndSurface::GetShapeResult 
569   (const Handle(IGESData_IGESEntity)& start) const
570 {
571   TopoDS_Shape res;
572
573   DeclareAndCast(TransferBRep_ShapeBinder, binder, myTP->Find(start));
574   if (binder.IsNull()) return res;
575   if (binder->HasResult())
576     res = binder->Result();
577   return res;
578 }
579
580
581 //=======================================================================
582 //function : SetShapeResult
583 //purpose  : 
584 //=======================================================================
585
586 void IGESToBRep_CurveAndSurface::SetShapeResult 
587   (const Handle(IGESData_IGESEntity)& start,
588    const TopoDS_Shape& result)
589 {
590   Handle(TransferBRep_ShapeBinder) binder = new TransferBRep_ShapeBinder;
591   myTP->Bind(start,binder);
592   binder->SetResult(result);
593 }
594
595 //=======================================================================
596 //function : NbShapeResult
597 //purpose  : 
598 //=======================================================================
599
600 Standard_Integer IGESToBRep_CurveAndSurface::NbShapeResult 
601   (const Handle(IGESData_IGESEntity)& start) const
602 {
603   Standard_Integer nbres = 0;
604   DeclareAndCast(TransferBRep_ShapeListBinder,binder,myTP->Find(start));
605   if (binder.IsNull()) return nbres;
606   nbres = binder->NbShapes();
607   return nbres;
608 }
609
610
611 //=======================================================================
612 //function : GetShapeResult
613 //purpose  : 
614 //=======================================================================
615
616 TopoDS_Shape IGESToBRep_CurveAndSurface::GetShapeResult 
617   (const Handle(IGESData_IGESEntity)& start, const Standard_Integer num) const
618 {
619   TopoDS_Shape res;
620
621   DeclareAndCast(TransferBRep_ShapeListBinder,binder,myTP->Find(start));
622   if (binder.IsNull()) return res;
623   
624   if (num <= binder->NbShapes()) 
625     res = binder->Shape(num);
626   return res;
627 }
628
629
630 //=======================================================================
631 //function : AddShapeResult
632 //purpose  : 
633 //=======================================================================
634
635 void IGESToBRep_CurveAndSurface::AddShapeResult 
636   (const Handle(IGESData_IGESEntity)& start,
637    const TopoDS_Shape& result)
638 {
639   DeclareAndCast(TransferBRep_ShapeListBinder,binder,myTP->Find(start));
640   if (binder.IsNull()){
641     binder = new TransferBRep_ShapeListBinder;
642     myTP->Bind(start,binder);
643   }
644   binder->AddResult(result);
645 }
646
647 void IGESToBRep_CurveAndSurface::SetSurface(const Handle(Geom_Surface)& theSurface)
648 {
649   if(mySurface!=theSurface) {
650     mySurface = theSurface;
651     myIsResolCom = Standard_False;
652     myUVResolution = 0.;
653   }
654 }
655
656 Handle(Geom_Surface) IGESToBRep_CurveAndSurface::Surface() const 
657 {
658   return mySurface;
659 }
660
661 Standard_Real IGESToBRep_CurveAndSurface::GetUVResolution()
662 {
663   if(!myIsResolCom && !mySurface.IsNull()) {
664     myIsResolCom = Standard_True;
665     GeomAdaptor_Surface aGAS(mySurface);
666     myUVResolution = Min(aGAS.UResolution(1.), aGAS.VResolution(1.));
667   }
668   return myUVResolution;
669 }
670
671
672
673
674
675