mirror of
https://git.dev.opencascade.org/repos/occt.git
synced 2025-04-06 18:26:22 +03:00
1172 lines
37 KiB
C++
Executable File
1172 lines
37 KiB
C++
Executable File
// Copyright (c) 1999-2012 OPEN CASCADE SAS
|
|
//
|
|
// The content of this file is subject to the Open CASCADE Technology Public
|
|
// License Version 6.5 (the "License"). You may not use the content of this file
|
|
// except in compliance with the License. Please obtain a copy of the License
|
|
// at http://www.opencascade.org and read it completely before using this file.
|
|
//
|
|
// The Initial Developer of the Original Code is Open CASCADE S.A.S., having its
|
|
// main offices at: 1, place des Freres Montgolfier, 78280 Guyancourt, France.
|
|
//
|
|
// The Original Code and all software distributed under the License is
|
|
// distributed on an "AS IS" basis, without warranty of any kind, and the
|
|
// Initial Developer hereby disclaims all such warranties, including without
|
|
// limitation, any warranties of merchantability, fitness for a particular
|
|
// purpose or non-infringement. Please see the License for the specific terms
|
|
// and conditions governing the rights and limitations under the License.
|
|
|
|
// List of changes:
|
|
//skl 29.01.2003 - deleted one space symbol at the begining
|
|
// of strings from Header Section
|
|
#include <StepData_StepWriter.ixx>
|
|
#include <StepData_WriterLib.hxx>
|
|
#include <StepData_ReadWriteModule.hxx>
|
|
#include <StepData_Protocol.hxx>
|
|
#include <StepData_UndefinedEntity.hxx>
|
|
#include <TCollection_HAsciiString.hxx>
|
|
#include <StepData_SelectMember.hxx>
|
|
#include <StepData_SelectArrReal.hxx>
|
|
|
|
#include <Interface_EntityIterator.hxx>
|
|
#include <Interface_ReportEntity.hxx>
|
|
#include <Interface_Check.hxx>
|
|
#include <Interface_InterfaceMismatch.hxx>
|
|
#include <Standard_NoSuchObject.hxx>
|
|
#include <Interface_Macros.hxx>
|
|
#include <stdio.h>
|
|
|
|
#define StepLong 72
|
|
// StepLong : longueur maxi d une ligne de fichier Step
|
|
|
|
|
|
// Constantes litterales (interessantes, pour les performances ET LA MEMOIRE)
|
|
|
|
static TCollection_AsciiString textscope (" &SCOPE");
|
|
static TCollection_AsciiString textendscope (" ENDSCOPE");
|
|
static TCollection_AsciiString textcomm (" /* ");
|
|
static TCollection_AsciiString textendcomm (" */");
|
|
static TCollection_AsciiString textlist ("(");
|
|
static TCollection_AsciiString textendlist (")");
|
|
static TCollection_AsciiString textendent (");");
|
|
static TCollection_AsciiString textparam (",");
|
|
static TCollection_AsciiString textundef ("$");
|
|
static TCollection_AsciiString textderived ("*");
|
|
static TCollection_AsciiString texttrue (".T.");
|
|
static TCollection_AsciiString textfalse (".F.");
|
|
static TCollection_AsciiString textunknown (".U.");
|
|
|
|
|
|
|
|
//=======================================================================
|
|
//function : StepData_StepWriter
|
|
//purpose :
|
|
//=======================================================================
|
|
|
|
StepData_StepWriter::StepData_StepWriter(const Handle(StepData_StepModel)& amodel)
|
|
: thecurr (StepLong) , thefloatw (12)
|
|
{
|
|
themodel = amodel; thelabmode = thetypmode = 0;
|
|
thefile = new TColStd_HSequenceOfHAsciiString();
|
|
thesect = Standard_False; thefirst = Standard_True;
|
|
themult = Standard_False; thecomm = Standard_False;
|
|
thelevel = theindval = 0; theindent = Standard_False;
|
|
// Format flottant : reporte dans le FloatWriter
|
|
}
|
|
|
|
// .... Controle d Envoi des Flottants ....
|
|
|
|
//=======================================================================
|
|
//function : FloatWriter
|
|
//purpose :
|
|
//=======================================================================
|
|
|
|
Interface_FloatWriter& StepData_StepWriter::FloatWriter ()
|
|
{ return thefloatw; } // s y reporter
|
|
|
|
|
|
//=======================================================================
|
|
//function : LabelMode
|
|
//purpose :
|
|
//=======================================================================
|
|
|
|
Standard_Integer& StepData_StepWriter::LabelMode ()
|
|
{ return thelabmode; }
|
|
|
|
|
|
//=======================================================================
|
|
//function : TypeMode
|
|
//purpose :
|
|
//=======================================================================
|
|
|
|
Standard_Integer& StepData_StepWriter::TypeMode ()
|
|
{ return thetypmode; }
|
|
|
|
// .... Description des Scopes (AVANT Envoi) ....
|
|
|
|
|
|
//=======================================================================
|
|
//function : SetScope
|
|
//purpose :
|
|
//=======================================================================
|
|
|
|
void StepData_StepWriter::SetScope (const Standard_Integer numscope,
|
|
const Standard_Integer numin)
|
|
{
|
|
Standard_Integer nb = themodel->NbEntities();
|
|
if (numscope <= 0 || numscope > nb || numin <= 0 || numin > nb)
|
|
Interface_InterfaceMismatch::Raise("StepWriter : SetScope, out of range");
|
|
if (thescopenext.IsNull()) {
|
|
thescopebeg = new TColStd_HArray1OfInteger (1,nb); thescopebeg->Init(0);
|
|
thescopeend = new TColStd_HArray1OfInteger (1,nb); thescopeend->Init(0);
|
|
thescopenext = new TColStd_HArray1OfInteger (1,nb); thescopenext->Init(0);
|
|
}
|
|
else if (thescopenext->Value(numin) != 0) {
|
|
#ifdef DEB
|
|
cout << "StepWriter : SetScope (scope : " << numscope << " entity : "
|
|
<< numin << "), Entity already in a Scope"<<endl;
|
|
#endif
|
|
Interface_InterfaceMismatch::Raise("StepWriter : SetScope, already set");
|
|
}
|
|
thescopenext->SetValue(numin,-1); // nouvelle fin de scope
|
|
if (thescopebeg->Value(numscope) == 0) thescopebeg->SetValue(numscope,numin);
|
|
Standard_Integer lastin = thescopeend->Value(numscope);
|
|
if (lastin > 0) thescopenext->SetValue(lastin,numin);
|
|
thescopeend->SetValue(numscope,numin);
|
|
}
|
|
|
|
|
|
//=======================================================================
|
|
//function : IsInScope
|
|
//purpose :
|
|
//=======================================================================
|
|
|
|
Standard_Boolean StepData_StepWriter::IsInScope(const Standard_Integer num) const
|
|
{
|
|
if (thescopenext.IsNull()) return Standard_False;
|
|
return (thescopenext->Value(num) != 0);
|
|
}
|
|
|
|
// ###########################################################################
|
|
// ## ## ## ## ENVOI DES SECTIONS ## ## ## ##
|
|
|
|
// .... Envoi du Modele Complet ....
|
|
|
|
|
|
//=======================================================================
|
|
//function : SendModel
|
|
//purpose :
|
|
//=======================================================================
|
|
|
|
void StepData_StepWriter::SendModel(const Handle(StepData_Protocol)& protocol,
|
|
const Standard_Boolean headeronly)
|
|
{
|
|
StepData_WriterLib lib(protocol);
|
|
|
|
if (!headeronly)
|
|
thefile->Append (new TCollection_HAsciiString("ISO-10303-21;"));
|
|
SendHeader();
|
|
|
|
// .... Header : suite d entites sans Ident ....
|
|
|
|
Interface_EntityIterator header = themodel->Header();
|
|
thenum = 0;
|
|
for (header.Start(); header.More(); header.Next()) {
|
|
Handle(Standard_Transient) anent = header.Value();
|
|
|
|
// Write Entity via Lib (similaire a SendEntity)
|
|
Handle(StepData_ReadWriteModule) module; Standard_Integer CN;
|
|
if (lib.Select(anent,module,CN)) {
|
|
if (module->IsComplex(CN)) StartComplex();
|
|
else {
|
|
TCollection_AsciiString styp;
|
|
if (thetypmode > 0) styp = module->ShortType(CN);
|
|
if (styp.Length() == 0) styp = module->StepType(CN);
|
|
StartEntity (styp);
|
|
}
|
|
module->WriteStep(CN,*this,anent);
|
|
if (module->IsComplex(CN)) EndComplex();
|
|
} else {
|
|
// Pas trouve ci-dessus ... tenter UndefinedEntity
|
|
DeclareAndCast(StepData_UndefinedEntity,und,anent);
|
|
if (und.IsNull()) continue;
|
|
if (und->IsComplex()) StartComplex();
|
|
und->WriteParams(*this);
|
|
if (und->IsComplex()) EndComplex();
|
|
}
|
|
EndEntity ();
|
|
}
|
|
EndSec();
|
|
if (headeronly) return;
|
|
|
|
// Data : Comme Header mais avec des Idents ... sinon le code est le meme
|
|
SendData();
|
|
|
|
// .... Erreurs Globales (silya) ....
|
|
|
|
Handle(Interface_Check) achglob = themodel->GlobalCheck();
|
|
Standard_Integer nbfails = achglob->NbFails();
|
|
if (nbfails > 0) {
|
|
Comment(Standard_True);
|
|
SendComment("GLOBAL FAIL MESSAGES, recorded at Read time :");
|
|
for (Standard_Integer ifail = 1; ifail <= nbfails; ifail ++) {
|
|
SendComment (achglob->Fail(ifail));
|
|
}
|
|
Comment(Standard_False);
|
|
NewLine(Standard_False);
|
|
}
|
|
|
|
// .... Sortie des Entites une par une ....
|
|
|
|
Standard_Integer nb = themodel->NbEntities();
|
|
for (Standard_Integer i = 1 ; i <= nb; i ++) {
|
|
// Liste principale : on n envoie pas les Entites dans un Scope
|
|
// Elles le seront par l intermediaire du Scope qui les contient
|
|
if (!thescopebeg.IsNull()) { if (thescopenext->Value(i) != 0) continue; }
|
|
SendEntity (i,lib);
|
|
}
|
|
|
|
EndSec();
|
|
EndFile();
|
|
}
|
|
|
|
|
|
// .... DECOUPAGE DU FICHIER EN SECTIONS ....
|
|
|
|
|
|
//=======================================================================
|
|
//function : SendHeader
|
|
//purpose :
|
|
//=======================================================================
|
|
|
|
void StepData_StepWriter::SendHeader ()
|
|
{
|
|
NewLine(Standard_False);
|
|
thefile->Append (new TCollection_HAsciiString("HEADER;"));
|
|
thesect = Standard_True;
|
|
}
|
|
|
|
|
|
//=======================================================================
|
|
//function : SendData
|
|
//purpose :
|
|
//=======================================================================
|
|
|
|
void StepData_StepWriter::SendData ()
|
|
{
|
|
if (thesect) Interface_InterfaceMismatch::Raise("StepWriter : Data section");
|
|
NewLine(Standard_False);
|
|
thefile->Append (new TCollection_HAsciiString("DATA;"));
|
|
thesect = Standard_True;
|
|
}
|
|
|
|
|
|
//=======================================================================
|
|
//function : EndSec
|
|
//purpose :
|
|
//=======================================================================
|
|
|
|
void StepData_StepWriter::EndSec ()
|
|
{
|
|
thefile->Append (new TCollection_HAsciiString("ENDSEC;"));
|
|
thesect = Standard_False;
|
|
}
|
|
|
|
|
|
//=======================================================================
|
|
//function : EndFile
|
|
//purpose :
|
|
//=======================================================================
|
|
|
|
void StepData_StepWriter::EndFile ()
|
|
{
|
|
if (thesect) Interface_InterfaceMismatch::Raise("StepWriter : EndFile");
|
|
NewLine(Standard_False);
|
|
thefile->Append (new TCollection_HAsciiString("END-ISO-10303-21;"));
|
|
thesect = Standard_False;
|
|
}
|
|
|
|
// .... ENVOI D UNE ENTITE ....
|
|
|
|
|
|
//=======================================================================
|
|
//function : SendEntity
|
|
|
|
//purpose :
|
|
//=======================================================================
|
|
|
|
void StepData_StepWriter::SendEntity(const Standard_Integer num,
|
|
const StepData_WriterLib& lib)
|
|
{
|
|
char lident[20];
|
|
Handle(Standard_Transient) anent = themodel->Entity(num);
|
|
Standard_Integer idnum = num , idtrue = 0;
|
|
|
|
// themodel->Number(anent) et-ou IdentLabel(anent)
|
|
if (thelabmode > 0) idtrue = themodel->IdentLabel(anent);
|
|
if (thelabmode == 1) idnum = idtrue;
|
|
if (idnum == 0) idnum = num;
|
|
if (thelabmode < 2 || idnum == idtrue) sprintf(lident,"#%d = ",idnum); //skl 29.01.2003
|
|
else sprintf(lident,"%d:#%d = ",idnum,idtrue); //skl 29.01.2003
|
|
|
|
// SendIdent repris , lident vient d etre calcule
|
|
thecurr.Clear();
|
|
thecurr.Add (lident);
|
|
themult = Standard_False;
|
|
|
|
// .... Traitement du Scope Eventuel
|
|
if (!thescopebeg.IsNull()) {
|
|
Standard_Integer numin = thescopebeg->Value(num);
|
|
if (numin != 0) {
|
|
SendScope();
|
|
for (Standard_Integer nument = numin; numin > 0; nument = numin) {
|
|
SendEntity(nument,lib);
|
|
numin = thescopenext->Value(nument);
|
|
}
|
|
SendEndscope();
|
|
}
|
|
}
|
|
|
|
// .... Envoi de l Entite proprement dite
|
|
|
|
// Write Entity via Lib
|
|
thenum = num;
|
|
Handle(StepData_ReadWriteModule) module; Standard_Integer CN;
|
|
if (themodel->IsRedefinedContent(num)) {
|
|
// Entite Erreur : Ecrire le Contenu + les Erreurs en Commentaires
|
|
Handle(Interface_ReportEntity) rep = themodel->ReportEntity(num);
|
|
DeclareAndCast(StepData_UndefinedEntity,und,rep->Content());
|
|
if (und.IsNull()) {
|
|
thechecks.CCheck(num)->AddFail("Erroneous Entity, Content lost");
|
|
StartEntity(TCollection_AsciiString("!?LOST_DATA"));
|
|
} else {
|
|
thechecks.CCheck(num)->AddWarning("Erroneous Entity, equivalent content");
|
|
if (und->IsComplex()) AddString(" (",2);
|
|
und->WriteParams(*this);
|
|
if (und->IsComplex()) { AddString(") ",2); } //thelevel --; }
|
|
}
|
|
EndEntity (); // AVANT les Commentaires
|
|
NewLine(Standard_False);
|
|
Comment(Standard_True);
|
|
if (und.IsNull()) SendComment(" ERRONEOUS ENTITY, DATA LOST");
|
|
SendComment("On Entity above, Fail Messages recorded at Read time :");
|
|
Handle(Interface_Check) ach = rep->Check();
|
|
Standard_Integer nbfails = ach->NbFails();
|
|
for (Standard_Integer ifail = 1; ifail <= nbfails; ifail ++) {
|
|
SendComment (ach->Fail(ifail));
|
|
}
|
|
Comment(Standard_False);
|
|
NewLine(Standard_False);
|
|
|
|
// Cas normal
|
|
}
|
|
else if (lib.Select(anent,module,CN)) {
|
|
if (module->IsComplex(CN)) StartComplex();
|
|
else {
|
|
TCollection_AsciiString styp;
|
|
if (thetypmode > 0) styp = module->ShortType(CN);
|
|
if (styp.Length() == 0) styp = module->StepType(CN);
|
|
StartEntity (styp);
|
|
}
|
|
module->WriteStep(CN,*this,anent);
|
|
if (module->IsComplex(CN)) EndComplex();
|
|
EndEntity ();
|
|
}
|
|
else {
|
|
// Pas trouve ci-dessus ... tenter UndefinedEntity
|
|
DeclareAndCast(StepData_UndefinedEntity,und,anent);
|
|
if (und.IsNull()) return;
|
|
if (und->IsComplex()) StartComplex();
|
|
und->WriteParams(*this);
|
|
if (und->IsComplex()) EndComplex();
|
|
EndEntity ();
|
|
}
|
|
}
|
|
|
|
// ###########################################################################
|
|
// ## ## ## CONSTITUTION DU TEXTE A ENVOYER ## ## ##
|
|
|
|
// Passer a la ligne. Ligne vide pas comptee sauf si evenempty == Standard_True
|
|
|
|
|
|
//=======================================================================
|
|
//function : NewLine
|
|
//purpose :
|
|
//=======================================================================
|
|
|
|
void StepData_StepWriter::NewLine (const Standard_Boolean evenempty)
|
|
{
|
|
if (evenempty || thecurr.Length() > 0) {
|
|
thefile->Append(thecurr.Moved());
|
|
}
|
|
Standard_Integer indst = thelevel * 2; if (theindent) indst += theindval;
|
|
thecurr.SetInitial(indst); thecurr.Clear();
|
|
}
|
|
|
|
|
|
// Regrouper ligne en cours avec precedente; reste en cours sauf si newline
|
|
// == Standard_True, auquel cas on commence une nouvelle ligne
|
|
// Ne fait rien si : total correspondant > StepLong ou debut ou fin d`entite
|
|
|
|
|
|
//=======================================================================
|
|
//function : JoinLast
|
|
//purpose :
|
|
//=======================================================================
|
|
|
|
void StepData_StepWriter::JoinLast (const Standard_Boolean newline)
|
|
{
|
|
/*
|
|
Handle(TCollection_HAsciiString) lst = thefile->Last();
|
|
Standard_Integer lng = lst->Length();
|
|
if (thecurr.Length() == 0) return;
|
|
if (lng + thecurr.Length() > StepLong) return;
|
|
if (lst->Value(1) == '#' || lst->Search(";") > 0) return;
|
|
lst->AssignCat(thecurr.Moved());
|
|
if (!newline) {
|
|
thecurr.Add (lst->ToCString(),lst->Length());
|
|
thefile->Remove(thefile->Length());
|
|
thecurr.SetInitial(0); .. inclus dans lst ...
|
|
}
|
|
*/
|
|
thecurr.SetKeep();
|
|
}
|
|
|
|
|
|
//=======================================================================
|
|
//function : Indent
|
|
//purpose :
|
|
//=======================================================================
|
|
|
|
void StepData_StepWriter::Indent (const Standard_Boolean onent)
|
|
{ theindent = onent; }
|
|
|
|
|
|
//=======================================================================
|
|
//function : SendIdent
|
|
//purpose :
|
|
//=======================================================================
|
|
|
|
void StepData_StepWriter::SendIdent(const Standard_Integer ident)
|
|
{
|
|
char lident[12];
|
|
sprintf(lident,"#%d =",ident);
|
|
thecurr.Clear();
|
|
thecurr.Add (lident);
|
|
themult = Standard_False;
|
|
}
|
|
|
|
|
|
//=======================================================================
|
|
//function : SendScope
|
|
//purpose :
|
|
//=======================================================================
|
|
|
|
void StepData_StepWriter::SendScope ()
|
|
{ AddString(textscope); }
|
|
|
|
|
|
//=======================================================================
|
|
//function : SendEndscope
|
|
//purpose :
|
|
//=======================================================================
|
|
|
|
void StepData_StepWriter::SendEndscope ()
|
|
{
|
|
NewLine(Standard_False);
|
|
thefile->Append(new TCollection_HAsciiString(textendscope));
|
|
}
|
|
|
|
|
|
//=======================================================================
|
|
//function : Comment
|
|
//purpose :
|
|
//=======================================================================
|
|
|
|
void StepData_StepWriter::Comment (const Standard_Boolean mode)
|
|
{
|
|
if (mode && !thecomm) AddString(textcomm,20);
|
|
if (!mode && thecomm) AddString(textendcomm);
|
|
thecomm = mode;
|
|
}
|
|
|
|
|
|
//=======================================================================
|
|
//function : SendComment
|
|
//purpose :
|
|
//=======================================================================
|
|
|
|
void StepData_StepWriter::SendComment(const Handle(TCollection_HAsciiString)& text)
|
|
{
|
|
if (!thecomm) Interface_InterfaceMismatch::Raise("StepWriter : Comment");
|
|
AddString(text->ToCString(),text->Length());
|
|
}
|
|
|
|
|
|
//=======================================================================
|
|
//function : SendComment
|
|
//purpose :
|
|
//=======================================================================
|
|
|
|
void StepData_StepWriter::SendComment (const Standard_CString text)
|
|
{
|
|
if (!thecomm) Interface_InterfaceMismatch::Raise("StepWriter : Comment");
|
|
AddString(text,strlen(text));
|
|
}
|
|
|
|
|
|
//=======================================================================
|
|
//function : StartEntity
|
|
//purpose :
|
|
//=======================================================================
|
|
|
|
void StepData_StepWriter::StartEntity(const TCollection_AsciiString& atype)
|
|
{
|
|
if (atype.Length() == 0) return;
|
|
if (themult) {
|
|
if (thelevel != 1) Interface_InterfaceMismatch::Raise
|
|
("StepWriter : StartEntity"); // decompte de parentheses mauvais ...
|
|
AddString(textendlist);
|
|
AddString(" ",1); //skl 29.01.2003
|
|
}
|
|
themult = Standard_True;
|
|
//AddString(" ",1); //skl 29.01.2003
|
|
AddString(atype);
|
|
thelevel = 0;
|
|
theindval = thecurr.Length();
|
|
thecurr.SetInitial(0);
|
|
thefirst = Standard_True;
|
|
OpenSub();
|
|
}
|
|
|
|
|
|
//=======================================================================
|
|
//function : StartComplex
|
|
//purpose :
|
|
//=======================================================================
|
|
|
|
void StepData_StepWriter::StartComplex ()
|
|
{
|
|
AddString("( ",2); //skl 29.01.2003
|
|
} // thelevel unchanged
|
|
|
|
|
|
//=======================================================================
|
|
//function : EndComplex
|
|
//purpose :
|
|
//=======================================================================
|
|
|
|
void StepData_StepWriter::EndComplex ()
|
|
{ AddString(") ",2); } // thelevel unchanged
|
|
|
|
|
|
// .... SendField et ce qui va avec
|
|
|
|
|
|
//=======================================================================
|
|
//function : SendField
|
|
//purpose :
|
|
//=======================================================================
|
|
|
|
void StepData_StepWriter::SendField(const StepData_Field& fild,
|
|
const Handle(StepData_PDescr)& descr)
|
|
{
|
|
Standard_Boolean done = Standard_True;
|
|
Standard_Integer kind = fild.Kind (Standard_False); // valeur interne
|
|
|
|
if (kind == 16) {
|
|
DeclareAndCast(StepData_SelectMember,sm,fild.Transient());
|
|
SendSelect (sm,descr);
|
|
return;
|
|
}
|
|
switch (kind) {
|
|
// ici les cas simples; ensuite on caste et on voit
|
|
case 0 : SendUndef(); break;
|
|
case 1 : Send (fild.Integer ()); break;
|
|
case 2 : SendBoolean (fild.Boolean ()); break;
|
|
case 3 : SendLogical (fild.Logical ()); break;
|
|
case 4 : SendEnum (fild.EnumText ()); break; // enum : descr ?
|
|
case 5 : Send (fild.Real ()); break;
|
|
case 6 : Send (fild.String ()); break;
|
|
case 7 : Send (fild.Entity ()); break;
|
|
case 8 : done = Standard_False; break;
|
|
case 9 : SendDerived (); break;
|
|
default: done = Standard_False; break;
|
|
}
|
|
if (done) return;
|
|
|
|
// Que reste-t-il : les tableaux ...
|
|
Standard_Integer arity = fild.Arity();
|
|
if (arity == 0) { SendUndef(); return; } // PAS NORMAL
|
|
if (arity == 1) {
|
|
OpenSub();
|
|
Standard_Integer i,low = fild.Lower(), up = low + fild.Length() - 1;
|
|
for (i = low; i <= up; i ++) {
|
|
kind = fild.ItemKind(i);
|
|
done = Standard_True;
|
|
switch (kind) {
|
|
case 0 : SendUndef(); break;
|
|
case 1 : Send (fild.Integer (i)); break;
|
|
case 2 : SendBoolean (fild.Boolean (i)); break;
|
|
case 3 : SendLogical (fild.Logical (i)); break;
|
|
case 4 : SendEnum (fild.EnumText (i)); break;
|
|
case 5 : Send (fild.Real (i)); break;
|
|
case 6 : Send (fild.String (i)); break;
|
|
case 7 : Send (fild.Entity (i)); break;
|
|
default: SendUndef(); done = Standard_False; break; // ANORMAL
|
|
}
|
|
}
|
|
CloseSub();
|
|
return;
|
|
}
|
|
if (arity == 2) {
|
|
OpenSub();
|
|
Standard_Integer j,low1 = fild.Lower(1), up1 = low1 + fild.Length(1) - 1;
|
|
for (j = low1; j <= up1; j ++) {
|
|
Standard_Integer i=0,low2 = fild.Lower(2), up2 = low2 + fild.Length(2) - 1;
|
|
OpenSub();
|
|
for (i = low2; i <= up2; i ++) {
|
|
kind = fild.ItemKind(i,j);
|
|
done = Standard_True;
|
|
switch (kind) {
|
|
case 0 : SendUndef(); break;
|
|
case 1 : Send (fild.Integer (i,j)); break;
|
|
case 2 : SendBoolean (fild.Boolean (i,j)); break;
|
|
case 3 : SendLogical (fild.Logical (i,j)); break;
|
|
case 4 : SendEnum (fild.EnumText (i,j)); break;
|
|
case 5 : Send (fild.Real (i,j)); break;
|
|
case 6 : Send (fild.String (i,j)); break;
|
|
case 7 : Send (fild.Entity (i,j)); break;
|
|
default: SendUndef(); done = Standard_False; break; // ANORMAL
|
|
}
|
|
}
|
|
CloseSub();
|
|
}
|
|
CloseSub();
|
|
return;
|
|
}
|
|
}
|
|
|
|
|
|
//=======================================================================
|
|
//function : SendSelect
|
|
//purpose :
|
|
//=======================================================================
|
|
|
|
void StepData_StepWriter::SendSelect(const Handle(StepData_SelectMember)& sm,
|
|
const Handle(StepData_PDescr)& descr)
|
|
{
|
|
// Cas du SelectMember. Traiter le Select puis la valeur
|
|
// NB : traitement actuel non recursif (pas de SELNAME(SELNAME(..)) )
|
|
Standard_Boolean selname = Standard_False;
|
|
if (sm.IsNull()) return; // ??
|
|
if (sm->HasName()) {
|
|
selname = Standard_True;
|
|
// SendString (sm->Name());
|
|
// AddString(textlist); // SANS AJOUT DE PARAMETRE !!
|
|
OpenTypedSub (sm->Name());
|
|
}
|
|
Standard_Integer kind = sm->Kind();
|
|
switch (kind) {
|
|
case 0 : SendUndef(); break;
|
|
case 1 : Send (sm->Integer ()); break;
|
|
case 2 : SendBoolean (sm->Boolean ()); break;
|
|
case 3 : SendLogical (sm->Logical ()); break;
|
|
case 4 : SendEnum (sm->EnumText ()); break; // enum : descr ?
|
|
case 5 : Send (sm->Real ()); break;
|
|
case 6 : Send (sm->String ()); break;
|
|
case 8 : SendArrReal (Handle(StepData_SelectArrReal)::DownCast(sm)->ArrReal()); break;
|
|
default: break; // ??
|
|
}
|
|
if (selname) CloseSub();
|
|
}
|
|
|
|
|
|
//=======================================================================
|
|
//function : SendList
|
|
//purpose :
|
|
//=======================================================================
|
|
|
|
void StepData_StepWriter::SendList(const StepData_FieldList& list,
|
|
const Handle(StepData_ESDescr)& descr)
|
|
{
|
|
// start entity ?
|
|
Standard_Integer i, nb = list.NbFields();
|
|
for (i = 1; i <= nb; i ++) {
|
|
Handle(StepData_PDescr) pde;
|
|
if (!descr.IsNull()) pde = descr->Field(i);
|
|
const StepData_Field fild = list.Field(i);
|
|
SendField (fild,pde);
|
|
}
|
|
// end entity ?
|
|
}
|
|
|
|
// .... Send* de base
|
|
|
|
|
|
//=======================================================================
|
|
//function : OpenSub
|
|
//purpose :
|
|
//=======================================================================
|
|
|
|
void StepData_StepWriter::OpenSub ()
|
|
{
|
|
AddParam();
|
|
AddString(textlist);
|
|
thefirst = Standard_True;
|
|
thelevel ++;
|
|
}
|
|
|
|
|
|
//=======================================================================
|
|
//function : OpenTypedSub
|
|
//purpose :
|
|
//=======================================================================
|
|
|
|
void StepData_StepWriter::OpenTypedSub (const Standard_CString subtype)
|
|
{
|
|
AddParam();
|
|
if (subtype[0] != '\0') AddString (subtype,strlen(subtype));
|
|
AddString(textlist);
|
|
thefirst = Standard_True;
|
|
thelevel ++;
|
|
}
|
|
|
|
|
|
//=======================================================================
|
|
//function : CloseSub
|
|
//purpose :
|
|
//=======================================================================
|
|
|
|
void StepData_StepWriter::CloseSub ()
|
|
{
|
|
AddString(textendlist);
|
|
thefirst = Standard_False; // le parametre suivant une sous-liste n est donc pas 1er
|
|
thelevel --;
|
|
}
|
|
|
|
|
|
//=======================================================================
|
|
//function : AddParam
|
|
//purpose :
|
|
//=======================================================================
|
|
|
|
void StepData_StepWriter::AddParam ()
|
|
{
|
|
if (!thefirst) AddString(textparam);
|
|
thefirst = Standard_False;
|
|
}
|
|
|
|
|
|
//=======================================================================
|
|
//function : Send
|
|
//purpose :
|
|
//=======================================================================
|
|
|
|
void StepData_StepWriter::Send (const Standard_Integer val)
|
|
{
|
|
char lval[12];
|
|
AddParam();
|
|
sprintf(lval,"%d",val);
|
|
AddString(lval,strlen(lval));
|
|
}
|
|
|
|
|
|
//=======================================================================
|
|
//function : Send
|
|
//purpose :
|
|
//=======================================================================
|
|
|
|
void StepData_StepWriter::Send (const Standard_Real val)
|
|
{
|
|
// Valeur flottante, expurgee de "0000" qui trainent et de "E+00"
|
|
char lval[24];
|
|
Standard_Integer lng = thefloatw.Write(val,lval);
|
|
AddParam();
|
|
AddString(lval,lng); // gere le format specifique : si besoin est
|
|
}
|
|
|
|
// Send(String) : attention, on envoie un Texte ... donc entre ' '
|
|
|
|
//=======================================================================
|
|
//function : Send
|
|
//purpose :
|
|
//=======================================================================
|
|
|
|
void StepData_StepWriter::Send (const TCollection_AsciiString& val)
|
|
{
|
|
AddParam();
|
|
TCollection_AsciiString aval(val); // on duplique pour trafiquer si besoin
|
|
Standard_Integer nb = aval.Length(); Standard_Integer nn = nb;
|
|
aval.AssignCat('\''); // comme cela, Insert(i+1) est OK
|
|
|
|
// Conversion des Caracteres speciaux
|
|
for (Standard_Integer i = nb; i > 0; i --) {
|
|
char uncar = aval.Value(i);
|
|
if (uncar == '\'') { aval.Insert(i+1,'\''); nn ++; continue; }
|
|
if (uncar == '\\') { aval.Insert(i+1,'\\'); nn ++; continue; }
|
|
if (uncar == '\n') { aval.SetValue(i,'\\'); aval.Insert(i+1,'\\');
|
|
aval.Insert(i+1,'N' ); nn += 2; continue; }
|
|
if (uncar == '\t') { aval.SetValue(i,'\\'); aval.Insert(i+1,'\\');
|
|
aval.Insert(i+1,'T' ); nn += 2; continue; }
|
|
}
|
|
//:i2 abv 31 Aug 98: ProSTEP TR9: avoid wrapping text or do it at spaces
|
|
aval.Insert(1,'\'');
|
|
nn += 2;
|
|
|
|
//:i2 AddString ("\'",1); nn ++;
|
|
|
|
// Attention au depassement des 72 caracteres
|
|
if (thecurr.CanGet(nn)) AddString(aval,0);
|
|
//:i2
|
|
else {
|
|
thefile->Append(thecurr.Moved());
|
|
Standard_Integer indst = thelevel * 2; if (theindent) indst += theindval;
|
|
if ( indst+nn <= StepLong ) thecurr.SetInitial(indst);
|
|
else thecurr.SetInitial(0);
|
|
if ( thecurr.CanGet(nn) ) AddString(aval,0);
|
|
else {
|
|
while ( nn >0 ) {
|
|
if (nn <= StepLong) {
|
|
thecurr.Add (aval); // Ca yet, on a tout epuise
|
|
thecurr.FreezeInitial();
|
|
break;
|
|
}
|
|
Standard_Integer stop = StepLong; // position of last separator
|
|
for ( ; stop > 0 && aval.Value(stop) != ' '; stop-- );
|
|
if ( ! stop ) {
|
|
stop = StepLong;
|
|
for ( ; stop > 0 && aval.Value(stop) != '\\'; stop-- );
|
|
if ( ! stop ) {
|
|
stop = StepLong;
|
|
for ( ; stop > 0 && aval.Value(stop) != '_'; stop-- );
|
|
if ( ! stop ) stop = StepLong;
|
|
}
|
|
}
|
|
TCollection_AsciiString bval = aval.Split(stop);
|
|
thefile->Append(new TCollection_HAsciiString(aval));
|
|
aval = bval;
|
|
nn -= stop;
|
|
}
|
|
}
|
|
}
|
|
/* //:i2
|
|
else {
|
|
// Il faut tronconner ... lignes limitees a 72 caracteres (StepLong)
|
|
Standard_Integer ncurr = thecurr.Length();
|
|
Standard_Integer nbuff = StepLong - ncurr;
|
|
thecurr.Add (aval.ToCString(),nbuff);
|
|
thefile->Append(thecurr.Moved());
|
|
aval.Remove(1,nbuff);
|
|
nn -= nbuff;
|
|
while (nn > 0) {
|
|
if (nn <= StepLong) {
|
|
thecurr.Add (aval); // Ca yet, on a tout epuise
|
|
thecurr.FreezeInitial();
|
|
break;
|
|
}
|
|
TCollection_AsciiString bval = aval.Split(StepLong);
|
|
thefile->Append(new TCollection_HAsciiString(bval));
|
|
nn -= StepLong;
|
|
}
|
|
}
|
|
//:i2 */
|
|
// thecurr.Add('\''); deja mis dans aval au debut
|
|
}
|
|
|
|
|
|
//=======================================================================
|
|
//function : Send
|
|
//purpose :
|
|
//=======================================================================
|
|
|
|
void StepData_StepWriter::Send (const Handle(Standard_Transient)& val)
|
|
{
|
|
char lident[20];
|
|
// Undefined ?
|
|
if (val.IsNull()) {
|
|
// Interface_InterfaceMismatch::Raise("StepWriter : Sending Null Reference");
|
|
thechecks.CCheck(thenum)->AddFail("Null Reference");
|
|
SendUndef();
|
|
Comment(Standard_True);
|
|
SendComment(" NUL REF ");
|
|
Comment(Standard_False);
|
|
return;
|
|
}
|
|
Standard_Integer num = themodel->Number(val);
|
|
// String ? (si non repertoriee dans le Modele)
|
|
if (num == 0) {
|
|
if (val->IsKind(STANDARD_TYPE(TCollection_HAsciiString))) {
|
|
DeclareAndCast(TCollection_HAsciiString,strval,val);
|
|
Send (TCollection_AsciiString(strval->ToCString()));
|
|
return;
|
|
}
|
|
// SelectMember ? (toujours, si non repertoriee)
|
|
// mais attention, pas de description attachee
|
|
else if (val->IsKind(STANDARD_TYPE(StepData_SelectMember))) {
|
|
DeclareAndCast(StepData_SelectMember,sm,val);
|
|
Handle(StepData_PDescr) descr; // null
|
|
SendSelect (sm,descr);
|
|
}
|
|
// Sinon, PAS NORMAL !
|
|
else {
|
|
thechecks.CCheck(thenum)->AddFail("UnknownReference");
|
|
SendUndef();
|
|
Comment(Standard_True);
|
|
SendComment(" UNKNOWN REF ");
|
|
Comment(Standard_False);
|
|
// Interface_InterfaceMismatch::Raise("StepWriter : Sending Unknown Reference");
|
|
}
|
|
}
|
|
// Cas normal : une bonne Entite, on envoie son Ident.
|
|
else {
|
|
Standard_Integer idnum = num, idtrue = 0;
|
|
if (thelabmode > 0) idtrue = themodel->IdentLabel(val);
|
|
if (thelabmode == 1) idnum = idtrue;
|
|
if (idnum == 0) idnum = num;
|
|
if (thelabmode < 2 || idnum == idtrue) sprintf(lident,"#%d",idnum);
|
|
else sprintf(lident,"%d:#%d",idnum,idtrue);
|
|
AddParam();
|
|
AddString(lident,strlen(lident));
|
|
}
|
|
}
|
|
|
|
|
|
//=======================================================================
|
|
//function : SendBoolean
|
|
//purpose :
|
|
//=======================================================================
|
|
|
|
void StepData_StepWriter::SendBoolean (const Standard_Boolean val)
|
|
{
|
|
if (val) SendString(texttrue);
|
|
else SendString(textfalse);
|
|
}
|
|
|
|
|
|
//=======================================================================
|
|
//function : SendLogical
|
|
//purpose :
|
|
//=======================================================================
|
|
|
|
void StepData_StepWriter::SendLogical (const StepData_Logical val)
|
|
{
|
|
if (val == StepData_LTrue) SendString(texttrue);
|
|
else if (val == StepData_LFalse) SendString(textfalse);
|
|
else SendString(textunknown);
|
|
}
|
|
|
|
|
|
// SendString : attention, on donne l'intitule exact
|
|
|
|
//=======================================================================
|
|
//function : SendString
|
|
//purpose :
|
|
//=======================================================================
|
|
|
|
void StepData_StepWriter::SendString (const TCollection_AsciiString& val)
|
|
{
|
|
AddParam();
|
|
AddString(val);
|
|
}
|
|
|
|
// SendString : attention, on donne l'intitule exact
|
|
|
|
//=======================================================================
|
|
//function : SendString
|
|
//purpose :
|
|
//=======================================================================
|
|
|
|
void StepData_StepWriter::SendString (const Standard_CString val)
|
|
{
|
|
AddParam();
|
|
AddString(val,strlen(val));
|
|
}
|
|
|
|
// SendEnum : attention, on envoie un intitule d'Enum ... donc entre . .
|
|
|
|
//=======================================================================
|
|
//function : SendEnum
|
|
//purpose :
|
|
//=======================================================================
|
|
|
|
void StepData_StepWriter::SendEnum (const TCollection_AsciiString& val)
|
|
{
|
|
if (val.Length() == 1 && val.Value(1) == '$') { SendUndef(); return; }
|
|
AddParam();
|
|
TCollection_AsciiString aValue = val;
|
|
if (aValue.Value(1) != '.') aValue.Prepend('.');
|
|
if (aValue.Value(aValue.Length()) != '.') aValue+='.';
|
|
AddString(aValue,2);
|
|
|
|
}
|
|
|
|
// SendEnum : attention, on envoie un intitule d'Enum ... donc entre . .
|
|
|
|
//=======================================================================
|
|
//function : SendEnum
|
|
//purpose :
|
|
//=======================================================================
|
|
|
|
void StepData_StepWriter::SendEnum (const Standard_CString val)
|
|
{
|
|
|
|
if (val[0] == '$' && val[1] == '\0') { SendUndef(); return; }
|
|
TCollection_AsciiString aValue(val);
|
|
SendEnum(aValue);
|
|
}
|
|
|
|
|
|
//=======================================================================
|
|
//function : SendArrReal
|
|
//purpose :
|
|
//=======================================================================
|
|
|
|
void StepData_StepWriter::SendArrReal (const Handle(TColStd_HArray1OfReal) &anArr)
|
|
{
|
|
AddString(textlist);
|
|
if(anArr->Length()>0) {
|
|
// add real
|
|
Send(anArr->Value(1));
|
|
for( Standard_Integer i=2; i<=anArr->Length(); i++) {
|
|
// AddString(textparam);
|
|
//add real
|
|
Send(anArr->Value(i));
|
|
}
|
|
}
|
|
AddString(textendlist);
|
|
}
|
|
|
|
|
|
//=======================================================================
|
|
//function : SendUndef
|
|
//purpose :
|
|
//=======================================================================
|
|
|
|
void StepData_StepWriter::SendUndef ()
|
|
{
|
|
AddParam();
|
|
AddString(textundef);
|
|
}
|
|
|
|
|
|
//=======================================================================
|
|
//function : SendDerived
|
|
//purpose :
|
|
//=======================================================================
|
|
|
|
void StepData_StepWriter::SendDerived ()
|
|
{
|
|
AddParam();
|
|
AddString(textderived);
|
|
}
|
|
|
|
|
|
// EndEntity : s'il faut mettre ; a la ligne, l'aligner sur debut d'entite ...
|
|
|
|
//=======================================================================
|
|
//function : EndEntity
|
|
//purpose :
|
|
//=======================================================================
|
|
|
|
void StepData_StepWriter::EndEntity ()
|
|
{
|
|
if (thelevel != 1) Interface_InterfaceMismatch::Raise
|
|
("StepWriter : EndEntity"); // decompte de parentheses mauvais ...
|
|
AddString(textendent);
|
|
thelevel = 0; // on garde theindval : sera traite au prochain NewLine
|
|
Standard_Boolean indent = theindent; theindent = Standard_False;
|
|
NewLine(Standard_False); theindent = indent;
|
|
themult = Standard_False;
|
|
// pour forcer indentation si necessaire
|
|
}
|
|
|
|
|
|
// gestion de la ligne courante (cf aussi NewLine/JoinLine)
|
|
|
|
//=======================================================================
|
|
//function : AddString
|
|
//purpose :
|
|
//=======================================================================
|
|
|
|
void StepData_StepWriter::AddString(const TCollection_AsciiString& astr,
|
|
const Standard_Integer more)
|
|
{
|
|
while (!thecurr.CanGet(astr.Length() + more)) {
|
|
thefile->Append(thecurr.Moved());
|
|
Standard_Integer indst = thelevel * 2; if (theindent) indst += theindval;
|
|
thecurr.SetInitial(indst);
|
|
}
|
|
thecurr.Add(astr);
|
|
}
|
|
|
|
|
|
//=======================================================================
|
|
//function : AddString
|
|
//purpose :
|
|
//=======================================================================
|
|
|
|
void StepData_StepWriter::AddString(const Standard_CString astr,
|
|
const Standard_Integer lnstr,
|
|
const Standard_Integer more)
|
|
{
|
|
while (!thecurr.CanGet(lnstr + more)) {
|
|
thefile->Append(thecurr.Moved());
|
|
Standard_Integer indst = thelevel * 2; if (theindent) indst += theindval;
|
|
thecurr.SetInitial(indst);
|
|
}
|
|
thecurr.Add(astr,lnstr);
|
|
}
|
|
|
|
|
|
// ENVOI FINAL
|
|
|
|
|
|
//=======================================================================
|
|
//function : CheckList
|
|
//purpose :
|
|
//=======================================================================
|
|
|
|
Interface_CheckIterator StepData_StepWriter::CheckList () const
|
|
{
|
|
return thechecks;
|
|
}
|
|
|
|
|
|
//=======================================================================
|
|
//function : NbLines
|
|
//purpose :
|
|
//=======================================================================
|
|
|
|
Standard_Integer StepData_StepWriter::NbLines () const
|
|
{ return thefile->Length(); }
|
|
|
|
|
|
//=======================================================================
|
|
//function : Line
|
|
//purpose :
|
|
//=======================================================================
|
|
|
|
Handle(TCollection_HAsciiString) StepData_StepWriter::Line
|
|
(const Standard_Integer num) const
|
|
{ return thefile->Value(num); }
|
|
|
|
|
|
//=======================================================================
|
|
//function : Printw
|
|
//purpose :
|
|
//=======================================================================
|
|
|
|
Standard_Boolean StepData_StepWriter::Print (Standard_OStream& S)
|
|
{
|
|
Standard_Boolean isGood = (S.good());
|
|
Standard_Integer nb = thefile->Length();
|
|
for (Standard_Integer i = 1; i <= nb && isGood; i ++)
|
|
S << thefile->Value(i)->ToCString() << "\n";
|
|
|
|
S<< flush;
|
|
isGood = (S && S.good());
|
|
|
|
return isGood;
|
|
|
|
}
|