23d91152c5a6969d3deb47a34f031b7ab744ea6e
[occt.git] / src / IGESData / IGESData_IGESReaderTool.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
15 #include <IGESData_ColorEntity.hxx>
16 #include <IGESData_DirPart.hxx>
17 #include <IGESData_FileRecognizer.hxx>
18 #include <IGESData_IGESEntity.hxx>
19 #include <IGESData_IGESModel.hxx>
20 #include <IGESData_IGESReaderData.hxx>
21 #include <IGESData_IGESReaderTool.hxx>
22 #include <IGESData_LabelDisplayEntity.hxx>
23 #include <IGESData_LevelListEntity.hxx>
24 #include <IGESData_LineFontEntity.hxx>
25 #include <IGESData_ParamCursor.hxx>
26 #include <IGESData_ParamReader.hxx>
27 #include <IGESData_Protocol.hxx>
28 #include <IGESData_ReadWriteModule.hxx>
29 #include <IGESData_TransfEntity.hxx>
30 #include <IGESData_UndefinedEntity.hxx>
31 #include <IGESData_ViewKindEntity.hxx>
32 #include <Interface_Check.hxx>
33 #include <Interface_FileParameter.hxx>
34 #include <Interface_InterfaceModel.hxx>
35 #include <Interface_Macros.hxx>
36 #include <Interface_ParamList.hxx>
37 #include <Interface_ReaderModule.hxx>
38 #include <Message_Msg.hxx>
39 #include <Standard_Transient.hxx>
40 #include <TCollection_HAsciiString.hxx>
41
42 #include <stdio.h>
43 // MGE 17/06/98
44 // To use Msg class
45 IGESData_IGESReaderTool::IGESData_IGESReaderTool
46   (const Handle(IGESData_IGESReaderData)& reader,
47    const Handle(IGESData_Protocol)& protocol)
48       : theglib(protocol) , therlib(protocol)
49       {  SetData (reader,protocol);  }
50
51
52 //  ###########################################################################
53 //  ########                        PREPARATION                        ########
54
55     void IGESData_IGESReaderTool::Prepare
56   (const Handle(IGESData_FileRecognizer)& reco)
57 {
58   DeclareAndCast(IGESData_IGESReaderData,igesdat,Data());
59   igesdat->SetEntityNumbers();
60   thereco = reco;
61   SetEntities();
62   thelist = igesdat->Params(0);
63 }
64
65
66     Standard_Boolean IGESData_IGESReaderTool::Recognize
67   (const Standard_Integer num, Handle(Interface_Check)& ach,
68    Handle(Standard_Transient)& ent)
69 {
70   DeclareAndCast(IGESData_IGESReaderData,igesdat,Data());
71   thecnum = num;  thectyp = igesdat->DirType(num);
72   Handle(IGESData_IGESEntity) anent;
73   Standard_Boolean res = Standard_False;
74
75 //  Recognizer -> Liste limitative
76   if (!thereco.IsNull()) res = thereco->Evaluate(thectyp,anent);
77   if (res) ent = anent;
78 //  Sinon, Library
79   else res = RecognizeByLib (num,theglib,therlib,ach,ent);
80   return res;
81 }
82
83
84 //  ###########################################################################
85 //  ########                LECTURE  (Controle General)                ########
86
87 //    (Elements enchaines par la classe de base Interface_FileReaderTool)
88
89     void IGESData_IGESReaderTool::BeginRead
90   (const Handle(Interface_InterfaceModel)& amodel)
91 {
92   DeclareAndCast(IGESData_IGESModel,amod,amodel);
93   DeclareAndCast(IGESData_IGESReaderData,igesdat,Data());
94   const IGESData_GlobalSection& gs = igesdat->GlobalSection();
95   amod->SetStartSection  (igesdat->StartSection(),Standard_False);
96   amod->SetGlobalSection (gs);
97   Handle(Interface_Check) glob = amod->GlobalCheck();
98   glob->GetMessages (igesdat->GlobalCheck());
99   amod->SetGlobalCheck   (glob);
100   themaxweight  = gs.MaxLineWeight();
101   thegradweight = gs.LineWeightGrad();
102   if (thegradweight > 0)
103     { themaxweight = themaxweight/thegradweight; thegradweight = 1; }
104   thedefweight = igesdat->DefaultLineWeight();
105 }
106
107
108 // Manquent les procedures de reprise sur erreur en cours de route ...
109     Standard_Boolean  IGESData_IGESReaderTool::AnalyseRecord
110   (const Standard_Integer num, const Handle(Standard_Transient)& anent,
111    Handle(Interface_Check)& ach)
112 {
113
114   Handle(TCollection_HAsciiString) lab;
115
116   DeclareAndCast(IGESData_IGESEntity,ent,anent);
117   DeclareAndCast(IGESData_IGESReaderData,igesdat,Data());
118
119 //  Demarrage de la lecture : Faire Clear
120   ent->Clear();
121
122 //  UndefinedEntity : une pre-analyse est faite
123   DeclareAndCast(IGESData_UndefinedEntity,undent,ent);
124   if (!undent.IsNull()) {
125     IGESData_DirPart DP = igesdat->DirPart(num);    // qui le copie ...
126     undent->ReadDir (igesdat,DP,ach);               // DP a pu etre modifie
127     ReadDir (ent,igesdat,DP,ach);                   // Lecture avec ce DP
128   }
129   else ReadDir (ent,igesdat,igesdat->DirPart(num),ach);
130
131   thestep = IGESData_ReadDir;
132
133 //   Liste de Parametres : controle de son entete
134 //  Handle(Interface_ParamList) list = Data()->Params(num);
135   Standard_Integer nbpar = Data()->NbParams(num);
136   Standard_Integer n0par = (num == 1 ? 1 : (Data()->ParamFirstRank(num-1) +1));
137   if (nbpar < 1) {
138 //   Liste vide non admise, sauf si Undefined (par exemple type nul)
139     if (!undent.IsNull()) return Standard_True;
140     // Sending of message : DE : no parameter
141     Message_Msg Msg27 ("XSTEP_27");
142     Msg27.Arg(thecnum);
143     ach->SendFail(Msg27);
144     return Standard_False;
145   }
146   const Interface_FileParameter& FP = thelist->Value(n0par);
147   if ((FP.ParamType() != Interface_ParamInteger) || (atoi(FP.CValue()) != ent->TypeNumber()))
148     { 
149      // Sending of message : DE : Incorrect type 
150       Message_Msg Msg28 ("XSTEP_28");
151       Msg28.Arg(thecnum);
152       ach->SendFail(Msg28);  
153       return Standard_False; 
154     }
155
156   IGESData_ParamReader PR (thelist,ach,n0par,nbpar,num);
157   thestep = IGESData_ReadOwn;
158   ReadOwnParams (ent,igesdat,PR);
159   if ((thestep = PR.Stage()) == IGESData_ReadOwn) PR.NextStage();
160   if (thestep == IGESData_ReadEnd) {
161     if (!PR.IsCheckEmpty()) ach = PR.Check();
162     return (!ach->HasFailed());
163   }
164
165   ReadAssocs (ent,igesdat,PR);
166   if ((thestep = PR.Stage()) == IGESData_ReadAssocs) PR.NextStage();
167   if (thestep == IGESData_ReadEnd) {
168     if (!PR.IsCheckEmpty()) ach = PR.Check();
169     return (!ach->HasFailed());
170   }
171   ReadProps (ent,igesdat,PR);
172 //  thestep = IGESData_ReadEnd;
173   if   (!PR.IsCheckEmpty()) ach = PR.Check();
174   return (!ach->HasFailed());
175 }
176
177     void IGESData_IGESReaderTool::EndRead
178   (const Handle(Interface_InterfaceModel)& /* amodel */)
179 {
180 /*
181   DeclareAndCast(IGESData_IGESModel,amod,amodel);
182   DeclareAndCast(IGESData_IGESReaderData,igesdat,Data());
183   amod->SetLineWeights(igesdat->DefaultLineWeight());
184 */
185 }
186
187
188
189 //  ###########################################################################
190 //  ########                        UNE  ENTITE                        ########
191
192 //  ########                      Directory  Part                      ########
193
194     void  IGESData_IGESReaderTool::ReadDir
195   (const Handle(IGESData_IGESEntity)& ent,
196    const Handle(IGESData_IGESReaderData)& IR,
197    const IGESData_DirPart& DP, Handle(Interface_Check)& ach) const 
198
199     
200   Standard_Integer v[17];
201   Standard_Character nom[9]; Standard_Character snum[9], theRes1[9],theRes2[9];
202   //char mess[50]; //szv#4:S4163:12Mar99 unused
203
204   DP.Values(v[0],v[1],v[2],v[3],v[4],v[5],v[6],v[7],v[8],v[9],v[10],v[11],
205             v[12],v[13],v[14],v[15],v[16],theRes1,theRes2,nom,snum);
206
207   ent->InitTypeAndForm (v[0] , v[16]);
208   Handle(IGESData_IGESEntity) fieldent, Structure, fieldlab;
209   if (v[2] <  0) Structure  = GetCasted
210     (IGESData_IGESEntity,          IR->BoundEntity( (1-v[2])/2 ));
211
212   Handle(IGESData_LineFontEntity) Lnf;
213   if (v[3] <  0) {
214     fieldent = GetCasted(IGESData_IGESEntity, IR->BoundEntity( (1-v[3])/2 ));
215     Lnf = GetCasted(IGESData_LineFontEntity, fieldent);
216     if (Lnf.IsNull()) {
217       // Sending of message : Incorrect Line Font Pattern
218       Message_Msg Msg29 ("XSTEP_29");
219       Msg29.Arg(thecnum);
220       Msg29.Arg(thectyp.Type());
221       ach->SendWarning(Msg29);
222       ent->InitDirFieldEntity(4,fieldent);
223     }
224     else ent->InitLineFont (Lnf);
225   }
226   else ent->InitLineFont(Lnf,v[3]);    // ici Lnf Null
227
228   Handle(IGESData_LevelListEntity) Lvs;
229   if (v[4] <  0) {
230     fieldent = GetCasted(IGESData_IGESEntity, IR->BoundEntity( (1-v[4])/2 ));
231     Lvs = GetCasted(IGESData_LevelListEntity, fieldent);
232     if (Lvs.IsNull()) {
233       // Sending of message : Incorrect Line Font Pattern
234       Message_Msg Msg30 ("XSTEP_30");
235       Msg30.Arg(thecnum);
236       Msg30.Arg(thectyp.Type());
237       ach->SendWarning(Msg30);
238       ent->InitDirFieldEntity(5,fieldent);
239     }
240     else ent->InitLevel(Lvs,-1);
241   }
242   else ent->InitLevel(Lvs,v[4]);       // ici Lvs Null
243
244   if (v[5] != 0) {
245     fieldent = GetCasted(IGESData_IGESEntity,IR->BoundEntity( (1+v[5])/2 ));
246     DeclareAndCast(IGESData_ViewKindEntity,View,fieldent);
247     if (View.IsNull()) {
248       // Sending of message : Incorrect View 
249       Message_Msg Msg31 ("XSTEP_31");
250       Msg31.Arg(thecnum);
251       Msg31.Arg(thectyp.Type());
252       ach->SendWarning(Msg31);
253       ent->InitDirFieldEntity(6,fieldent);
254     }
255     else ent->InitView(View);
256   }
257
258   if (v[6] != 0) {
259     fieldent = GetCasted(IGESData_IGESEntity,IR->BoundEntity( (1+v[6])/2 ));
260     DeclareAndCast(IGESData_TransfEntity,Transf,fieldent);
261     if (Transf.IsNull()) {
262       // Sending of message : Incorrect Transformation Matrix 
263       Message_Msg Msg32 ("XSTEP_32");
264       Msg32.Arg(thecnum);
265       Msg32.Arg(thectyp.Type());
266       ach->SendWarning(Msg32);
267       ent->InitDirFieldEntity(7,fieldent);
268     }
269     else ent->InitTransf(Transf);
270   }
271
272   Handle(IGESData_LabelDisplayEntity) Lbd;
273   if (v[7] != 0) {
274     fieldlab = GetCasted(IGESData_IGESEntity,IR->BoundEntity( (1+v[7])/2 ));
275     Lbd = GetCasted(IGESData_LabelDisplayEntity,fieldent);
276     if (Lbd.IsNull()) {
277       // Sending of message : Incorrect Label Display 
278       Message_Msg Msg33 ("XSTEP_33");
279       Msg33.Arg(thecnum);
280       Msg33.Arg(thectyp.Type());
281       ach->SendWarning(Msg33);
282     }
283   }
284
285   ent->InitStatus (v[8] , v[9] , v[10] , v[11]);
286
287   Standard_Integer LWeightNum  = v[13];
288
289   Handle(IGESData_ColorEntity) Color;
290   if (v[14] <  0) {
291     fieldent = GetCasted(IGESData_IGESEntity,IR->BoundEntity( (1-v[14])/2 ));
292     Color = GetCasted(IGESData_ColorEntity, fieldent);
293     if (Color.IsNull()) {
294       // Sending of message : Incorrect Color Number 
295       Message_Msg Msg34 ("XSTEP_34");
296       Msg34.Arg(thecnum);
297       Msg34.Arg(thectyp.Type());
298       ach->SendWarning(Msg34);
299       ent->InitDirFieldEntity(13,fieldent);
300     }
301     else ent->InitColor(Color);
302   }
303   else ent->InitColor(Color,v[14]);
304
305   ent->InitMisc (Structure,Lbd,LWeightNum);
306   ent->InitDirFieldEntity(8,fieldlab);
307
308 // ignores : 1(type),2(ptrPsect),13(type),16(lignesPsect),17(form)
309 // type et forme sont lus directement du DirPart; autres infos recalculees
310
311 //    Restent a analyser nom (short label) et snum (subscript number)
312   Handle(TCollection_HAsciiString) ShortLabel;
313   Standard_Integer SubScriptN = -1;
314   Standard_Integer iacar = 0;
315   Standard_Integer i; // svv Jan11 2000 : porting on DEC
316   for (i = 0; i < 8; i ++) { if (nom[i] > ' ') iacar = 1;  }
317   if (iacar > 0) ShortLabel = new TCollection_HAsciiString(nom);
318   iacar = 0;
319   for (i = 0; i < 8; i ++)
320     {  if (snum[i] > ' ') iacar = 1; if(snum[i] == 0) break;  }
321   if (iacar > 0) SubScriptN = atoi(snum);
322   ent->SetLabel(ShortLabel,SubScriptN);
323
324 //    Enfin, SetLineWeight, tenant compte du defaut
325   ent->SetLineWeight (IR->DefaultLineWeight(),themaxweight,thegradweight);
326 }
327
328
329 //  ########                     Partie Specifique                     ########
330
331     void  IGESData_IGESReaderTool::ReadOwnParams
332   (const Handle(IGESData_IGESEntity)& ent,
333    const Handle(IGESData_IGESReaderData)& IR,
334    IGESData_ParamReader& PR) const 
335 {
336   Handle(Interface_Check) ach = new Interface_Check;;
337   Handle(Interface_ReaderModule) imodule;
338   Standard_Integer CN;
339   
340 //  Les Modules font tout
341   if (therlib.Select(ent,imodule,CN))
342   {
343     Handle(IGESData_ReadWriteModule) module =
344       Handle(IGESData_ReadWriteModule)::DownCast (imodule);
345     module->ReadOwnParams(CN,ent,IR,PR);
346   }
347   else if (ent.IsNull()) {
348 //  Pas trouve dutout
349     // Sending of message : Null Entity
350     Message_Msg Msg35 ("XSTEP_35");
351     Msg35.Arg(thecnum);
352     ach->SendFail(Msg35);
353 //  Cas de UndefinedEntity
354   } else if (ent->IsKind(STANDARD_TYPE(IGESData_UndefinedEntity))) {
355     DeclareAndCast(IGESData_UndefinedEntity,undent,ent);
356     undent->ReadOwnParams(IR,PR);
357 //    IGESEntity creee puis non reconnue ... (bizarre, non ?)
358   } else {
359 //    IGESData_IGESType DT = ent->IGESType();
360     // Sending of message : Unknown Entity
361     Message_Msg Msg36 ("XSTEP_36");
362     Msg36.Arg(thecnum);
363     ach->SendFail(Msg36);
364   }
365 }
366
367
368 //  ########                        Proprietes                         ########
369
370     void  IGESData_IGESReaderTool::ReadProps
371   (const Handle(IGESData_IGESEntity)& ent,
372    const Handle(IGESData_IGESReaderData)& IR,
373    IGESData_ParamReader& PR) const 
374 {
375  // MGE 17/06/98
376  // Building of Messages
377  //=====================================
378  Message_Msg Msg38 ("XSTEP_38");
379  //Message_Msg Msg221 ("XSTEP_221");
380  //=====================================
381  Handle(Interface_Check) ach = new Interface_Check;
382   Msg38.Arg(thecnum);
383   Msg38.Arg(thectyp.Type());
384  if (PR.Stage() != IGESData_ReadProps) ach->SendFail(Msg38);
385   Standard_Integer ncur = PR.CurrentNumber();
386   Standard_Integer nbp  = PR.NbParams();
387   if (ncur == nbp + 1) {  PR.EndAll();  return;  }
388   else if (ncur > nbp || ncur == 0) ach->SendWarning(Msg38);
389
390   Standard_Integer nbprops = 0;
391   if (!PR.DefinedElseSkip()) return;
392   if (!PR.ReadInteger(ncur,nbprops)) {
393     Message_Msg Msg221 ("XSTEP_221");
394     PR.SendFail(Msg221);
395     return;
396   }
397   if (nbprops == 0)
398   {
399     return;
400   }
401
402   ++ncur;
403   Interface_EntityList props;
404   if (PR.ReadEntList
405       (IR,PR.CurrentList(nbprops),Msg38, props,Standard_False) )
406     ent->LoadProperties(props);
407 }
408
409
410 //  ########                      Associativites                       ########
411
412     void  IGESData_IGESReaderTool::ReadAssocs
413   (const Handle(IGESData_IGESEntity)& ent,
414    const Handle(IGESData_IGESReaderData)& IR,
415    IGESData_ParamReader& PR) const 
416 {
417   // MGE 17/06/98
418   // Building of Messages
419   //=====================================
420   Message_Msg Msg37 ("XSTEP_37");
421 //  Message_Msg Msg220 ("XSTEP_220");
422   //=====================================
423   Msg37.Arg(thecnum);
424   Msg37.Arg(thectyp.Type());
425   Handle(Interface_Check) ach = new Interface_Check;
426   if (PR.Stage() != IGESData_ReadAssocs) ach->SendFail(Msg37);
427   Standard_Integer ncur = PR.CurrentNumber(); 
428   Standard_Integer nbp  = PR.NbParams();
429   if (ncur == nbp + 1) {  PR.EndAll();  return;  }
430   else if (ncur > nbp || ncur == 0) ach->SendWarning(Msg37);
431
432   Standard_Integer nbassocs = 0;
433   if (!PR.DefinedElseSkip()) return;
434   if (!PR.ReadInteger(PR.Current(),nbassocs)){
435   Message_Msg Msg220 ("XSTEP_220");
436   PR.SendFail(Msg220);
437   return;
438 }
439   if (nbassocs == 0) return;
440   Interface_EntityList assocs;
441   if (PR.ReadEntList
442       (IR,PR.CurrentList(nbassocs),Msg37, assocs,Standard_False) )
443     ent->LoadAssociativities(assocs);
444 }