0030895: Coding Rules - specify std namespace explicitly for std::cout and streams
[occt.git] / src / IGESData / IGESData_BasicEditor.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 //#73 rln 10.03.99 S4135: "read.scale.unit" does not affect GlobalSection
15
16 #include <IGESData_BasicEditor.hxx>
17 #include <IGESData_ColorEntity.hxx>
18 #include <IGESData_DirChecker.hxx>
19 #include <IGESData_GeneralModule.hxx>
20 #include <IGESData_IGESEntity.hxx>
21 #include <IGESData_IGESModel.hxx>
22 #include <IGESData_LabelDisplayEntity.hxx>
23 #include <IGESData_LevelListEntity.hxx>
24 #include <IGESData_LineFontEntity.hxx>
25 #include <IGESData_Protocol.hxx>
26 #include <IGESData_SpecificModule.hxx>
27 #include <IGESData_TransfEntity.hxx>
28 #include <IGESData_ViewKindEntity.hxx>
29 #include <IGESGeom_Boundary.hxx>
30 #include <IGESGeom_CurveOnSurface.hxx>
31 #include <Interface_EntityIterator.hxx>
32 #include <Interface_Graph.hxx>
33 #include <Interface_Macros.hxx>
34 #include <Interface_Static.hxx>
35 #include <TCollection_HAsciiString.hxx>
36 #include <TColStd_Array1OfInteger.hxx>
37 #include <UnitsMethods.hxx>
38
39 IGESData_BasicEditor::IGESData_BasicEditor(const Handle(IGESData_Protocol)&  protocol)
40 {
41   Init(protocol);
42 }
43
44 IGESData_BasicEditor::IGESData_BasicEditor(const Handle(IGESData_IGESModel)& model,
45                                            const Handle(IGESData_Protocol)& protocol)
46 {
47   Init(model, protocol);
48 }
49
50 IGESData_BasicEditor::IGESData_BasicEditor() {  }
51
52 void IGESData_BasicEditor::Init (const Handle(IGESData_Protocol)& protocol)
53 {
54   theunit = Standard_False;
55   theproto = protocol;
56   themodel = GetCasted(IGESData_IGESModel,Interface_InterfaceModel::Template("iges"));
57   theglib = Interface_GeneralLib (protocol);
58   theslib = protocol;
59 }
60
61 void IGESData_BasicEditor::Init (const Handle(IGESData_IGESModel)& model, const Handle(IGESData_Protocol)& protocol)
62 {
63   theunit = Standard_False;
64   theproto = protocol;
65   themodel = model;
66   theglib = Interface_GeneralLib (protocol);
67   theslib = protocol;
68 }
69
70     Handle(IGESData_IGESModel)  IGESData_BasicEditor::Model () const
71       {  return themodel;  }
72
73 // ####   Travaux sur le Header (GlobalSection)    ####
74
75     Standard_Boolean IGESData_BasicEditor::SetUnitFlag
76   (const Standard_Integer flag)
77 {
78   if (themodel.IsNull()) return Standard_False;
79   if (flag < 1 || flag > 11) return Standard_False;
80   IGESData_GlobalSection GS = themodel->GlobalSection();
81   Handle(TCollection_HAsciiString) name = GS.UnitName();
82   Standard_CString nam = IGESData_BasicEditor::UnitFlagName (flag);
83   if (nam[0] != '\0') name = new TCollection_HAsciiString (nam);
84   GS.SetUnitFlag (flag);
85   GS.SetUnitName (name);
86   themodel->SetGlobalSection (GS);
87   theunit = Standard_True;
88   return Standard_True;
89 }
90
91     Standard_Boolean IGESData_BasicEditor::SetUnitValue
92   (const Standard_Real val)
93 {
94   if (val <= 0.) return Standard_False;
95   Standard_Real vmm = val * UnitsMethods::GetCasCadeLengthUnit(); //abv 20 Feb 00: adding cascade unit factor
96   //#73 rln 10.03.99 S4135: "read.scale.unit" does not affect GlobalSection
97   //if (Interface_Static::IVal("read.scale.unit") == 1) vmm = vmm * 1000.;
98 // vmm est exprime en MILLIMETRES
99   if (vmm >=      25.       && vmm <=      26.      ) return SetUnitFlag(1);
100   if (vmm >=       0.9      && vmm <=       1.1     ) return SetUnitFlag(2);
101   if (vmm >=     300.       && vmm <=     310.      ) return SetUnitFlag(4);
102   if (vmm >= 1600000.       && vmm <= 1620000.      ) return SetUnitFlag(5);
103   if (vmm >=     990.       && vmm <=    1010.      ) return SetUnitFlag(6);
104   if (vmm >=  990000.       && vmm <= 1010000.      ) return SetUnitFlag(7);
105   if (vmm >=       0.025    && vmm <=       0.026   ) return SetUnitFlag(8);
106   if (vmm >=       0.0009   && vmm <=       0.0011  ) return SetUnitFlag(9);
107   if (vmm >=       9.       && vmm <=      11.      ) return SetUnitFlag(10);
108   if (vmm >=       0.000025 && vmm <=       0.000026) return SetUnitFlag(11);
109   return Standard_False;
110 }
111
112 //=======================================================================
113 //function : SetUnitName
114 //purpose  : 
115 //=======================================================================
116 Standard_Boolean IGESData_BasicEditor::SetUnitName (const Standard_CString name)
117 {
118   if (themodel.IsNull()) return Standard_False;
119   Standard_Integer flag = IGESData_BasicEditor::UnitNameFlag (name);
120   IGESData_GlobalSection GS = themodel->GlobalSection();
121   if (GS.UnitFlag() == 3) {
122     char* nam = (char *)name;
123     if (name[1] == 'H') nam = (char *)&name[2];
124     GS.SetUnitName (new TCollection_HAsciiString(nam));
125     themodel->SetGlobalSection (GS);
126     return Standard_True;
127   }
128   if (flag > 0) return SetUnitFlag(flag);
129   return (flag > 0);
130 }
131
132     void  IGESData_BasicEditor::ApplyUnit (const Standard_Boolean enforce)
133 {
134   if (themodel.IsNull()) return;
135   if (!enforce && !theunit) return;
136   IGESData_GlobalSection GS = themodel->GlobalSection();
137   Standard_Real unit = GS.UnitValue();
138   if (unit <= 0.) return;
139   if (unit != 1.) {
140     GS.SetMaxLineWeight (GS.MaxLineWeight () / unit);
141     GS.SetResolution    (GS.Resolution    () / unit);
142     GS.SetMaxCoord      (GS.MaxCoord      () / unit);
143     themodel->SetGlobalSection (GS);
144   }
145   theunit = Standard_False;
146 }
147
148
149 // ####   Travaux globaux sur les entites    ####
150
151     void  IGESData_BasicEditor::ComputeStatus ()
152 {
153   if (themodel.IsNull()) return;
154   Standard_Integer nb = themodel->NbEntities();
155   if (nb == 0) return;
156   TColStd_Array1OfInteger subs (0,nb); subs.Init(0); // gere Subordinate Status
157   Interface_Graph G (themodel,theglib);    // gere & memorise UseFlag
158   G.ResetStatus();
159
160 //  2 phases : d abord on fait un calcul d ensemble. Ensuite on applique
161 //             Tout le modele est traite, pas de jaloux
162
163 //  Chaque entite va donner une contribution sur ses descendents propres :
164 //  pour Subordinate (1 ou 2 cumulables), pour UseFlag (1 a 6 exclusifs)
165 //    (6 depuis IGES-5.2)
166
167 //  Pour Subordinate : Drawing et 402 (sauf p-e dimensioned geometry ?) donnent
168 //   Logical, le reste implique Physical (sur descendants directs propres)
169
170 //  Pour UseFlag, un peu plus complique :
171 //  D une part, les UseFlag se propagent aux descendants directs ou non
172 //  D autre part les cas sont plus compliques (et pas aussi clairs)
173
174 //  ATTENTION, on ne peut traiter que ce qui se deduit du graphe en s appuyant
175 //  sur les "IGES Type Number", on n a pas le droit ici d acceder a la
176 //  description specifique des differents types : traites par AutoCorrect.
177 //  Exemple : une courbe est 3D ou parametrique 2D(UV), non seulement selon son
178 //  ascendant, mais selon le role qu elle y joue (ex. pour CurveOnSurface :
179 //  CurveUV/Curve3D)
180 //  Traites actuellement (necessaires) :
181 //  1(Annotation), aussi 4(pour maillage). 5(ParamUV) traite par AutoCorrect
182
183   Standard_Integer CN;
184   Standard_Integer i; // svv Jan11 2000 : porting on DEC
185   for (i = 1; i <= nb; i ++) {
186 //  Subordinate (sur directs en propre seulement)
187     Handle(IGESData_IGESEntity) ent = themodel->Entity(i);
188     Standard_Integer igt = ent->TypeNumber();
189     Handle(Interface_GeneralModule) gmodule;
190     if (theglib.Select (ent,gmodule,CN)) {
191       Handle(IGESData_GeneralModule) gmod =
192         Handle(IGESData_GeneralModule)::DownCast (gmodule);
193       Interface_EntityIterator sh;
194       gmod->OwnSharedCase (CN,ent,sh);
195       for (sh.Start(); sh.More(); sh.Next()) {
196         Standard_Integer nums = themodel->Number(sh.Value());
197         if (igt == 402 || igt == 404) subs.SetValue (nums,subs.Value(nums) | 2);
198         else subs.SetValue (nums,subs.Value(nums) | 1);
199 ////    std::cout<<"ComputeStatus : nums = "<<nums<<" ->"<<subs.Value(nums)<<std::endl;
200       }
201     }
202 //  UseFlag (a propager)
203     if (igt / 100 == 2) {
204       G.GetFromEntity(ent,Standard_True,1);               // Annotation
205       G.GetFromEntity(ent,Standard_False,ent->UseFlag());
206     } else if (igt == 134 || igt == 116 || igt == 132) {
207       Interface_EntityIterator sh = G.Sharings(ent);      // Maillage ...
208       if (sh.NbEntities() > 0) G.GetFromEntity(ent,Standard_True,4);
209 //  UV : voir AutoCorrect des classes concernees (Boundary et CurveOnSurface)
210 /*
211     } else if (ent->IsKind(STANDARD_TYPE(IGESGeom_CurveOnSurface))) {
212       DeclareAndCast(IGESGeom_CurveOnSurface,cos,ent);    // Curve UV
213       G.GetFromEntity (cos->CurveUV(),Standard_True,5);
214     } else if (ent->IsKind(STANDARD_TYPE(IGESGeom_Boundary))) {
215       DeclareAndCast(IGESGeom_Boundary,bnd,ent);          // Curve UV
216       Standard_Integer nc = bnd->NbModelSpaceCurves();
217       for (Standard_Integer ic = 1; ic <= nc; ic ++) {
218         Standard_Integer nuv = bnd->NbParameterCurves(ic);
219         for (Standard_Integer juv = 1; juv <= nuv; juv ++)
220           G.GetFromEntity(bnd->ParameterCurve(ic,juv),Standard_True,5);
221       }
222 */
223     }
224   }
225
226 //  A present, on va appliquer tout cela "de force"
227 //  Seule exception : des UseFlags non nuls deja en place sont laisses
228
229   for (i = 1; i <= nb; i ++) {
230     Handle(IGESData_IGESEntity) ent = themodel->Entity(i);
231     Standard_Integer bl = ent->BlankStatus();
232     Standard_Integer uf = ent->UseFlag();
233     if (uf == 0) uf = G.Status(i);
234     Standard_Integer hy = ent->HierarchyStatus();
235 ////    std::cout<<" Ent.n0."<<i<<" Subord="<<subs.Value(i)<<" Use="<<uf<<std::endl;
236     ent->InitStatus(bl,subs.Value(i),uf,hy);
237   }
238 }
239
240
241     Standard_Boolean  IGESData_BasicEditor::AutoCorrect
242   (const Handle(IGESData_IGESEntity)& ent)
243 {
244   if (themodel.IsNull()) return Standard_False;
245   Handle(IGESData_IGESEntity) bof, subent;
246   Handle(IGESData_LineFontEntity) linefont;
247   Handle(IGESData_LevelListEntity) levelist;
248   Handle(IGESData_ViewKindEntity) view;
249   Handle(IGESData_TransfEntity) transf;
250   Handle(IGESData_LabelDisplayEntity) labdisp;
251   Handle(IGESData_ColorEntity) color;
252
253   Standard_Boolean done = Standard_False;
254   if (ent.IsNull()) return done;
255 //    Corrections dans l entete (entites presentes)
256 //    On ne verifie pas les items "Shared", presents de toute facon
257 //    Entete : traite par DirChecker pour les cas standard
258 /*
259   linefont = ent->LineFont();
260   if (!linefont.IsNull() && themodel->Number(linefont) == 0) {
261     linefont.Nullify();
262     ent->InitLineFont(linefont,0);
263     done = Standard_True;
264   }
265   levelist = ent->LevelList();
266   if (!levelist.IsNull() && themodel->Number(levelist) == 0) {
267     levelist.Nullify();
268     ent->InitLevel(levelist,0);
269     done = Standard_True;
270   }
271   view = ent->View();
272   if (!view.IsNull() && themodel->Number(view) == 0) {
273     view.Nullify();
274     ent->InitView(view);
275     done = Standard_True;
276   }
277   transf = ent->Transf();
278   if (!transf.IsNull() && themodel->Number(transf) == 0) {
279     transf.Nullify();
280     ent->InitTransf(transf);
281     done = Standard_True;
282   }
283   labdisp = ent->LabelDisplay();
284   if (!labdisp.IsNull() && themodel->Number(labdisp) == 0) {
285     labdisp.Nullify();
286     ent->InitMisc (ent->Structure(),labdisp,ent->LineWeightNumber());
287     done = Standard_True;
288   }
289   color = ent->Color();
290   if (!color.IsNull() && themodel->Number(color) == 0) {
291     color.Nullify();
292     ent->InitColor(color,0);
293     done = Standard_True;
294   }
295 */
296
297 //    Corrections dans les Assocs (les Props restent attachees a l Entite)
298   Interface_EntityIterator iter = ent->Associativities();
299   for (iter.Start(); iter.More(); iter.Next()) {
300     subent = GetCasted(IGESData_IGESEntity,iter.Value());
301     if (!subent.IsNull() && themodel->Number(subent) == 0)
302       {  subent->Dissociate(ent);      done = Standard_True;  }
303   }
304
305 //    Corrections specifiques
306   Standard_Integer CN;
307   Handle(Interface_GeneralModule) gmodule;
308   if (theglib.Select (ent,gmodule,CN)) {
309     Handle(IGESData_GeneralModule) gmod =
310       Handle(IGESData_GeneralModule)::DownCast (gmodule);
311     IGESData_DirChecker DC = gmod->DirChecker(CN,ent);
312     done |= DC.Correct(ent);
313   }
314
315   Handle(IGESData_SpecificModule) smod;
316   if (theslib.Select (ent,smod,CN)) done |= smod->OwnCorrect (CN,ent);
317
318   return done;
319 }
320
321
322     Standard_Integer  IGESData_BasicEditor::AutoCorrectModel ()
323 {
324   Standard_Integer res = 0;
325   Standard_Integer nb = themodel->NbEntities();
326   for (Standard_Integer i = 1; i <= nb; i ++) {
327     if (AutoCorrect (themodel->Entity(i))) res ++;
328   }
329   return res;
330 }
331
332
333
334 //=======================================================================
335 //function : UnitNameFlag
336 //purpose  : 
337 //=======================================================================
338 Standard_Integer IGESData_BasicEditor::UnitNameFlag  (const Standard_CString name)
339 {
340   char* nam = (char *)&name[0];
341   if (name[1] == 'H') {
342     nam = (char *)&name[2];
343   }
344   if (!strcmp (nam,"INCH")) return 1;
345   if (!strcmp (nam,"IN"))   return 1;
346   if (!strcmp (nam,"MM"))   return 2;
347   if (!strcmp (nam,"FT"))   return 4;
348   if (!strcmp (nam,"MI"))   return 5;
349   if (!strcmp (nam,"M"))    return 6;
350   if (!strcmp (nam,"KM"))   return 7;
351   if (!strcmp (nam,"MIL"))  return 8;
352   if (!strcmp (nam,"UM"))   return 9;
353   if (!strcmp (nam,"CM"))   return 10;
354   if (!strcmp (nam,"UIN"))  return 11;
355   return 0;
356 }
357
358 Standard_Real IGESData_BasicEditor::UnitFlagValue (const Standard_Integer flag)
359 {
360   switch (flag) {
361     case  1 : return 0.0254;
362     case  2 : return 0.001;
363     case  3 : return 1.;
364     case  4 : return 0.3048;
365     case  5 : return 1609.27;
366     case  6 : return 1.;
367     case  7 : return 1000.;
368     case  8 : return 0.0000254;
369     case  9 : return 0.000001;
370     case 10 : return 0.01;
371     case 11 : return 0.0000000254;
372     default : break;
373   }
374   return 0.;
375 }
376
377 Standard_CString IGESData_BasicEditor::UnitFlagName (const Standard_Integer flag)
378 {
379   Standard_CString name = "";
380   switch (flag) {
381     case  1 : name = "INCH";  break;
382     case  2 : name = "MM";    break;
383     case  4 : name = "FT";    break;
384     case  5 : name = "MI";    break;
385     case  6 : name = "M";     break;
386     case  7 : name = "KM";    break;
387     case  8 : name = "MIL";   break;
388     case  9 : name = "UM";    break;
389     case 10 : name = "CM";    break;
390     case 11 : name = "UIN";   break;
391     default : break;
392   }
393   return name;
394 }
395
396 Standard_CString IGESData_BasicEditor::IGESVersionName (const Standard_Integer flag)
397 {
398   switch (flag) {
399     case 1 : return "1.0";
400     case 2 : return "ANSI Y14.26M-1981";
401     case 3 : return "2.0";
402     case 4 : return "3.0";
403     case 5 : return "ANSI Y14.26M-1987";
404     case 6 : return "4.0";
405     case 7 : return "ANSI Y14.26M-1989";
406     case 8 : return "5.0";
407     case 9 : return "5.1";
408     case 10: return "5.2";
409     case 11: return "5.3";
410     default : break;
411   }
412   return "";
413 }
414
415 Standard_Integer IGESData_BasicEditor::IGESVersionMax ()
416       {  return 11;  }
417
418 Standard_CString IGESData_BasicEditor::DraftingName (const Standard_Integer flag)
419 {
420   switch (flag) {
421     case 0 : return "(None)";
422     case 1 : return "ISO";
423     case 2 : return "AFNOR";
424     case 3 : return "ANSI";
425     case 4 : return "BSI";
426     case 5 : return "CSA";
427     case 6 : return "DIN";
428     case 7 : return "JIS";
429     default : break;
430   }
431   return "";
432 }
433
434 Standard_Integer IGESData_BasicEditor::DraftingMax ()
435       {  return 7;  }