0033661: Data Exchange, Step Import - Tessellated GDTs are not imported
[occt.git] / src / IGESGeom / IGESGeom_ToolBSplineCurve.cxx
1 // Created by: CKY / Contract Toubro-Larsen
2 // Copyright (c) 1993-1999 Matra Datavision
3 // Copyright (c) 1999-2014 OPEN CASCADE SAS
4 //
5 // This file is part of Open CASCADE Technology software library.
6 //
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.
12 //
13 // Alternatively, this file may be used under the terms of Open CASCADE
14 // commercial license or contractual agreement.
15
16 //--------------------------------------------------------------------
17 //--------------------------------------------------------------------
18 //#54 rln 24.12.98 CCI60005
19
20 #include <gp_XYZ.hxx>
21 #include <IGESData_DirChecker.hxx>
22 #include <IGESData_Dump.hxx>
23 #include <IGESData_IGESDumper.hxx>
24 #include <IGESData_IGESReaderData.hxx>
25 #include <IGESData_IGESWriter.hxx>
26 #include <IGESData_ParamCursor.hxx>
27 #include <IGESData_ParamReader.hxx>
28 #include <IGESGeom_BSplineCurve.hxx>
29 #include <IGESGeom_ToolBSplineCurve.hxx>
30 #include <Interface_Check.hxx>
31 #include <Interface_CopyTool.hxx>
32 #include <Interface_EntityIterator.hxx>
33 #include <Interface_Macros.hxx>
34 #include <Interface_ShareTool.hxx>
35 #include <Message_Messenger.hxx>
36 #include <Message_Msg.hxx>
37 #include <Standard_DomainError.hxx>
38 #include <TColgp_HArray1OfXYZ.hxx>
39 #include <TColStd_HArray1OfReal.hxx>
40
41 // MGE 29/07/98
42 //=======================================================================
43 //function : IGESGeom_ToolBSplineCurve
44 //purpose  : 
45 //=======================================================================
46 IGESGeom_ToolBSplineCurve::IGESGeom_ToolBSplineCurve ()
47 {
48 }
49
50
51 //=======================================================================
52 //function : ReadOwnParams
53 //purpose  : 
54 //=======================================================================
55
56 void IGESGeom_ToolBSplineCurve::ReadOwnParams(const Handle(IGESGeom_BSplineCurve)& ent,
57                                               const Handle(IGESData_IGESReaderData)& /* IR */,
58                                               IGESData_ParamReader& PR) const
59 {
60   // MGE 29/07/98
61   // Building of messages
62   //========================================
63   Message_Msg Msg99("XSTEP_99");
64   Message_Msg Msg100("XSTEP_100");
65   Message_Msg Msg101("XSTEP_101");
66   Message_Msg Msg102("XSTEP_102");
67   Message_Msg Msg103("XSTEP_103");
68   //========================================
69
70   Standard_Integer anIndex, aDegree;
71   Standard_Boolean aPlanar, aClosed, aPolynomial, aPeriodic;
72   Standard_Real aUmin, aUmax, normX,normY,normZ;
73   gp_XYZ aNorm (0.,0.,0.);
74   Handle(TColStd_HArray1OfReal) allKnots;
75   Handle(TColStd_HArray1OfReal) allWeights;
76   Handle(TColgp_HArray1OfXYZ)   allPoles;
77
78   //Standard_Boolean st; //szv#4:S4163:12Mar99 moved down
79
80   //st = PR.ReadInteger(PR.Current(), Msg97, anIndex); //szv#4:S4163:12Mar99 moved in if
81   //st = PR.ReadInteger(PR.Current(), "Upper Index Of Sum", anIndex);
82
83   //szv#4:S4163:12Mar99 optimized
84   /*if (st && anIndex >= 0) {
85     allPoles   = new TColgp_HArray1OfXYZ(0, anIndex);
86     // allWeights = new TColStd_HArray1OfReal(1, anIndex+1);  done by ReadReals
87   }
88   
89   if (st && anIndex < 0)
90   { 
91     PR.SendFail(Msg97);
92     anIndex = 0;
93   }*/
94   if (PR.ReadInteger(PR.Current(), anIndex)) {
95     if (anIndex < 0) {
96       Message_Msg Msg97("XSTEP_97");
97       PR.SendFail(Msg97);
98       anIndex = 0;
99     }
100     else {
101       allPoles   = new TColgp_HArray1OfXYZ(0, anIndex);
102       // allWeights = new TColStd_HArray1OfReal(1, anIndex+1);  done by ReadReals
103     }
104   }
105   else{
106     Message_Msg Msg97("XSTEP_97");
107     PR.SendFail(Msg97);
108   }
109
110   //st = PR.ReadInteger(PR.Current(), Msg98, aDegree); //szv#4:S4163:12Mar99 moved in if
111 //  if (st && ! allWeights.IsNull() )   done by ReadReals
112 //    allKnots = new TColStd_HArray1OfReal(-aDegree, anIndex+1);
113   if (!PR.ReadInteger(PR.Current(), aDegree)){
114     aDegree = 0; //szv#4:S4163:12Mar99 `st=` not needed
115     Message_Msg Msg98("XSTEP_98");
116     PR.SendFail(Msg98);
117   }
118   //szv#4:S4163:12Mar99 `st=` not needed
119   PR.ReadBoolean(PR.Current(), Msg99, aPlanar);
120   PR.ReadBoolean(PR.Current(), Msg100, aClosed);
121   PR.ReadBoolean(PR.Current(), Msg101, aPolynomial);
122   PR.ReadBoolean(PR.Current(), Msg102, aPeriodic);
123
124 //st = PR.ReadBoolean(PR.Current(), "Planar/Non Planar Flag", aPlanar);
125 //st = PR.ReadBoolean(PR.Current(), "Open/Closed Flag", aClosed);
126 //st = PR.ReadBoolean(PR.Current(), "Rational/Polynomial Flag", aPolynomial);
127 //st = PR.ReadBoolean(PR.Current(), "NonPeriodic/Periodic Flag", aPeriodic);
128
129   Standard_Integer nbKnots = anIndex + aDegree + 2;
130   // Reading all the knot sequences 
131
132   PR.ReadReals(PR.CurrentList(nbKnots), Msg103 , allKnots, -aDegree); //szv#4:S4163:12Mar99 `st=` not needed
133
134 //st = PR.ReadReals
135 //  (PR.CurrentList(nbKnots), "Knot sequence values", allKnots, -aDegree);
136
137   if (! allPoles.IsNull() )
138     {
139       Message_Msg Msg104("XSTEP_104");
140       Message_Msg Msg105("XSTEP_105");
141       PR.ReadReals(PR.CurrentList(anIndex+1), Msg104, allWeights,0); //szv#4:S4163:12Mar99 `st=` not needed
142       //st = PR.ReadReals(PR.CurrentList(anIndex+1), "Weights", allWeights,0);
143
144       for (Standard_Integer I = 0; I <= anIndex; I ++) 
145         {
146           gp_XYZ tempPole;
147           //st = PR.ReadXYZ(PR.CurrentList(1, 3), Msg105, tempPole); //szv#4:S4163:12Mar99 moved down
148           //st = PR.ReadXYZ(PR.CurrentList(1, 3), "Control Points", tempPole);
149           if (PR.ReadXYZ(PR.CurrentList(1, 3), Msg105, tempPole)) allPoles->SetValue(I, tempPole);
150         }
151     }
152
153   if (!PR.ReadReal(PR.Current(), aUmin)){
154     Message_Msg Msg106("XSTEP_106");
155     PR.SendFail(Msg106);
156   } //szv#4:S4163:12Mar99 `st=` not needed
157   if (!PR.ReadReal(PR.Current(), aUmax)){
158     Message_Msg Msg107("XSTEP_107");
159     PR.SendFail(Msg107);
160   } //szv#4:S4163:12Mar99 `st=` not needed
161 /*
162   st = PR.ReadReal(PR.Current(), "Starting Parameter Value", aUmin);
163   st = PR.ReadReal(PR.Current(), "Ending Parameter Value", aUmax);
164 */
165   Standard_Boolean st = Standard_False;
166   if (PR.DefinedElseSkip()){
167     st = PR.ReadReal(PR.Current(),  normX);
168     if(!st){
169       Message_Msg Msg108("XSTEP_108");
170       PR.SendFail(Msg108);
171     }
172   }
173     //st = PR.ReadReal(PR.Current(), "Unit Normal X", normX);
174   else normX = 0.;
175   if (PR.DefinedElseSkip()){
176     st = PR.ReadReal(PR.Current(),  normY);
177     if(!st){
178       Message_Msg Msg108("XSTEP_108");
179       PR.SendFail(Msg108);
180     }
181   }
182     //st = PR.ReadReal(PR.Current(), "Unit Normal Y", normY);
183   else normY = 0.;
184   if (PR.DefinedElseSkip()){
185     st = PR.ReadReal(PR.Current(), normZ);
186     if(!st){
187       Message_Msg Msg108("XSTEP_108");
188       PR.SendFail(Msg108);
189     }
190   }
191     //st = PR.ReadReal(PR.Current(), "Unit Normal Z", normZ);
192   else normZ = 0.;
193   if (st) aNorm.SetCoord(normX,normY,normZ);
194
195   DirChecker(ent).CheckTypeAndForm(PR.CCheck(),ent);
196   ent->Init
197     (anIndex,aDegree, aPlanar, aClosed, aPolynomial, aPeriodic,
198      allKnots, allWeights, allPoles, aUmin, aUmax, aNorm);
199 }
200
201
202 //=======================================================================
203 //function : WriteOwnParams
204 //purpose  : 
205 //=======================================================================
206
207 void IGESGeom_ToolBSplineCurve::WriteOwnParams
208   (const Handle(IGESGeom_BSplineCurve)& ent, IGESData_IGESWriter& IW)  const
209 {
210   Standard_Integer low, up ;
211   Standard_Integer I ;
212   Standard_Integer index  = ent->UpperIndex();
213   Standard_Integer degree = ent->Degree();
214   IW.Send(index);
215   IW.Send(degree);
216   IW.SendBoolean(ent->IsPlanar());
217   IW.SendBoolean(ent->IsClosed());
218   IW.SendBoolean(ent->IsPolynomial());
219   IW.SendBoolean(ent->IsPeriodic());
220
221   low = -degree;
222   up  = index + 1;
223   for (I = low; I <= up; I ++)
224     IW.Send(ent->Knot(I));
225
226   low = 0;
227   up  = index;
228   for (I = low; I <= up; I ++)
229     IW.Send(ent->Weight(I));
230
231   for (I = low; I <= up; I ++) {
232     IW.Send((ent->Pole(I)).X());
233     IW.Send((ent->Pole(I)).Y());
234     IW.Send((ent->Pole(I)).Z());
235   }
236   IW.Send(ent->UMin());
237   IW.Send(ent->UMax());
238   IW.Send(ent->Normal().X());
239   IW.Send(ent->Normal().Y());
240   IW.Send(ent->Normal().Z());
241 }
242
243
244 //=======================================================================
245 //function : OwnShared
246 //purpose  : 
247 //=======================================================================
248
249 void IGESGeom_ToolBSplineCurve::OwnShared(const Handle(IGESGeom_BSplineCurve)& /* ent */,
250                                           Interface_EntityIterator& /* iter */) const
251 {
252 }
253
254
255 //=======================================================================
256 //function : OwnCopy
257 //purpose  : 
258 //=======================================================================
259
260 void IGESGeom_ToolBSplineCurve::OwnCopy 
261   (const Handle(IGESGeom_BSplineCurve)& another,
262    const Handle(IGESGeom_BSplineCurve)& ent, Interface_CopyTool& /* TC */) const
263 {
264   Standard_Integer I;
265   Standard_Integer low, up;
266   Standard_Integer anIndex, aDegree;
267   Standard_Boolean aPlanar, aClosed, aPolynomial, aPeriodic;
268   Handle(TColStd_HArray1OfReal) allKnots, allWeights;
269   Handle(TColgp_HArray1OfXYZ) allPoles;
270   Standard_Real aUmin, aUmax;
271   gp_XYZ aNorm;
272
273   anIndex = another->UpperIndex();
274   aDegree = another->Degree();
275   aPlanar = another->IsPlanar();
276   aClosed = another->IsClosed();
277   aPolynomial = another->IsPolynomial();
278   aPeriodic = another->IsPeriodic();
279
280   allKnots = new TColStd_HArray1OfReal(-aDegree, anIndex+1);
281
282   low = -aDegree;
283   up  = anIndex + 1;
284   for (I = low; I <= up; I++)
285     allKnots->SetValue(I, another->Knot(I));
286
287   allWeights = new TColStd_HArray1OfReal(0, anIndex);
288
289   low = 0;
290   up  = anIndex;
291   for (I = low; I <= up; I++)
292     allWeights->SetValue(I, another->Weight(I));
293
294   allPoles = new TColgp_HArray1OfXYZ(0, anIndex);
295
296   for (I = low; I <= up; I++) 
297     allPoles->SetValue(I, (another->Pole(I)).XYZ());
298
299   aUmin = another->UMin();
300   aUmax = another->UMax();
301   aNorm = another->Normal();
302
303   ent->Init (anIndex,aDegree, aPlanar, aClosed, aPolynomial, aPeriodic,
304              allKnots, allWeights, allPoles, aUmin, aUmax, aNorm);
305 }
306
307
308 //=======================================================================
309 //function : DirChecker
310 //purpose  : 
311 //=======================================================================
312
313 IGESData_DirChecker IGESGeom_ToolBSplineCurve::DirChecker
314   (const Handle(IGESGeom_BSplineCurve)& /* ent */ )   const
315 {
316   IGESData_DirChecker DC(126, 0, 5);
317   DC.Structure(IGESData_DefVoid);
318   DC.LineFont(IGESData_DefAny);
319 //  DC.LineWeight(IGESData_DefValue);
320   DC.Color(IGESData_DefAny);
321   DC.HierarchyStatusIgnored();
322   return DC;
323 }
324
325
326 //=======================================================================
327 //function : OwnCheck
328 //purpose  : 
329 //=======================================================================
330
331 void IGESGeom_ToolBSplineCurve::OwnCheck(const Handle(IGESGeom_BSplineCurve)& ent,
332                                          const Interface_ShareTool&,
333                                          Handle(Interface_Check)& ach)  const
334 {
335   // MGE 29/07/98
336   // Building of messages
337   //========================================
338   //Message_Msg Msg104("XSTEP_104");
339   //Message_Msg Msg109("XSTEP_109");
340   //========================================
341
342   Standard_Real eps = 1.E-04;    // Tolerance des tests ??
343 //  Standard_Real norm = ent->Normal().SquareModulus();
344
345   //modified by rln 17/12/97 check of flag PROP2 according to IGES Standard
346   //It is possible to compare V(0) and V(1) only if StartingParameter = FirstKnot
347   //and EndingParameter = LastKnot (else we must build real geometrical curve)
348   //The fail is replaced with warning because it is not a serious problem
349   //if (ent->UMin() == ent->Knot(-ent->Degree()        ) &&
350   //  ent->UMax() == ent->Knot( ent->UpperIndex() + 1)   ) {
351   //  Standard_Real udif = ent->UMax() - ent->UMin();
352   //  if (udif < 0) udif = -udif;
353   //    Standard_Real udif = ent->Pole(0).SquareDistance (ent->Pole(ent->UpperIndex()));
354   //   if (udif <  eps * eps && !ent->IsClosed())
355   //     ach.AddWarning("V(0) == V(1) for an Open Curve (PROP2 = 0)");
356   //   if (udif >= eps * eps &&  ent->IsClosed())
357   //     ach.AddWarning("V(0) != V(1) for a Closed Curve (PROP2 = 1)");
358   //}
359
360   Standard_Integer lower = 0;
361   Standard_Integer upper = ent->UpperIndex();
362   Standard_Boolean Flag  = Standard_True;
363   
364   Standard_Integer I; // svv Jan 11 2000 : porting on DEC
365   for (I = 0; ((I < upper) && (Flag)); I++)
366     Flag &= (ent->Weight(I) > 0);
367   
368   if (!Flag) {
369     Message_Msg Msg104("XSTEP_104");
370     ach->SendFail(Msg104);
371   }
372   
373   Flag = Standard_True;
374   Standard_Real tempVal = ent->Weight(lower);
375   
376   for (I = lower; ((I < upper) && (Flag)); I++)
377     Flag &= (ent->Weight(I) == tempVal);
378 /*
379   if (Flag && !ent->IsPolynomial(Standard_True))
380     ach.AddWarning("All weights equal & PROP3 != 1 (Curve Not Polynomial)");
381   if (!Flag && ent->IsPolynomial(Standard_True))
382     ach.AddWarning("All weights not equal & PROP3 != 0 (Curve Not Rational)");
383 */
384
385   if (ent->IsPlanar()) {
386     gp_XYZ aNorm = ent->Normal();
387     Standard_Real epsn = eps * 10.;    // Tolerance ?? ici large
388     Standard_Real normod = aNorm.SquareModulus();
389     if (normod < epsn) {
390       Message_Msg Msg109("XSTEP_109");
391       ach->AddWarning(Msg109);
392     }
393   }
394 }
395
396
397 //=======================================================================
398 //function : OwnDump
399 //purpose  : 
400 //=======================================================================
401
402 void IGESGeom_ToolBSplineCurve::OwnDump(const Handle(IGESGeom_BSplineCurve)& ent,
403                                         const IGESData_IGESDumper& /* dumper */,
404                                         const Handle(Message_Messenger)& S,
405                                         const Standard_Integer level)  const
406 {
407   Standard_Integer upind = ent->UpperIndex();
408   S << "BSplineCurve from IGESGeom" << Message_EndLine;
409   S << "Sum UpperIndex : " << upind;
410   S << "   Degree : " << ent->Degree() << "  ";
411   S << (ent->IsPlanar() ? "Planar" : "NonPlanar") << Message_EndLine;
412   S << (ent->IsClosed() ? "Closed" : "Open") << "  ";
413   S << (ent->IsPeriodic() ? "Periodic" : "NonPeriodic") << "  ";//#54 rln 24.12.98 CCI60005
414   S << (ent->IsPolynomial(Standard_True) ? "Polynomial" : "Rational");
415
416   S << Message_EndLine << "Knots : ";
417   IGESData_DumpVals(S ,level,-ent->Degree(), upind+1,ent->Knot);
418   S << Message_EndLine << "Weights : ";
419   IGESData_DumpVals(S ,level,0, upind,ent->Weight);
420   S << Message_EndLine << "Control Points (Poles) : ";
421   IGESData_DumpListXYZL(S ,level,0, upind, ent->Pole, ent->Location());
422   S << Message_EndLine << "Starting Parameter Value : " << ent->UMin();
423   S << "  Ending Parameter Value : " << ent->UMax() << Message_EndLine;
424   S << "Unit Normal : ";
425   IGESData_DumpXYZL(S,level, ent->Normal(), ent->Location());
426   S << Message_EndLine;
427 }