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