mirror of
https://git.dev.opencascade.org/repos/occt.git
synced 2025-04-10 18:51:21 +03:00
A flag not to raise an exception is used on reading of an OCAF document. If such a shape with scaling transformation is stored in the document, it should be read. Modified files: XmlMNaming\XmlMNaming_NamedShapeDriver.cxx: not checking of the type of transformation for a read shape
418 lines
15 KiB
C++
418 lines
15 KiB
C++
// Created on: 2001-07-11
|
|
// Created by: Julia DOROVSKIKH
|
|
// Copyright (c) 2001-2014 OPEN CASCADE SAS
|
|
//
|
|
// This file is part of Open CASCADE Technology software library.
|
|
//
|
|
// This library is free software; you can redistribute it and/or modify it under
|
|
// the terms of the GNU Lesser General Public License version 2.1 as published
|
|
// by the Free Software Foundation, with special exception defined in the file
|
|
// OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
|
|
// distribution for complete text of the license and disclaimer of any warranty.
|
|
//
|
|
// Alternatively, this file may be used under the terms of Open CASCADE
|
|
// commercial license or contractual agreement.
|
|
|
|
//AGV 150202: Changed prototype LDOM_Node::getOwnerDocument()
|
|
|
|
#include <BRepTools.hxx>
|
|
#include <Message_Messenger.hxx>
|
|
#include <Message_ProgressScope.hxx>
|
|
#include <LDOM_OSStream.hxx>
|
|
#include <LDOM_Text.hxx>
|
|
#include <Standard_SStream.hxx>
|
|
#include <Standard_Type.hxx>
|
|
#include <TDF_Attribute.hxx>
|
|
#include <TDF_Label.hxx>
|
|
#include <TNaming_Builder.hxx>
|
|
#include <TNaming_Iterator.hxx>
|
|
#include <TNaming_NamedShape.hxx>
|
|
#include <TopoDS_Shape.hxx>
|
|
#include <TopTools_LocationSet.hxx>
|
|
#include <XmlLDrivers.hxx>
|
|
#include <XmlMNaming_NamedShapeDriver.hxx>
|
|
#include <XmlMNaming_Shape1.hxx>
|
|
#include <XmlObjMgt.hxx>
|
|
#include <XmlObjMgt_Array1.hxx>
|
|
#include <XmlObjMgt_Persistent.hxx>
|
|
|
|
IMPLEMENT_STANDARD_RTTIEXT(XmlMNaming_NamedShapeDriver,XmlMDF_ADriver)
|
|
|
|
static TNaming_Evolution EvolutionEnum (const XmlObjMgt_DOMString&);
|
|
static const XmlObjMgt_DOMString& EvolutionString (const TNaming_Evolution);
|
|
static void doTranslate (const TopoDS_Shape&,
|
|
XmlMNaming_Shape1&,
|
|
BRepTools_ShapeSet&);
|
|
static int doTranslate (const XmlMNaming_Shape1&,
|
|
TopoDS_Shape&,
|
|
BRepTools_ShapeSet&);
|
|
|
|
IMPLEMENT_DOMSTRING (OldsString, "olds")
|
|
IMPLEMENT_DOMSTRING (NewsString, "news")
|
|
IMPLEMENT_DOMSTRING (StatusString, "evolution")
|
|
IMPLEMENT_DOMSTRING (VersionString, "version")
|
|
IMPLEMENT_DOMSTRING (ShapesString, "shapes")
|
|
|
|
IMPLEMENT_DOMSTRING (EvolPrimitiveString, "primitive")
|
|
IMPLEMENT_DOMSTRING (EvolGeneratedString, "generated")
|
|
IMPLEMENT_DOMSTRING (EvolModifyString, "modify")
|
|
IMPLEMENT_DOMSTRING (EvolDeleteString, "delete")
|
|
IMPLEMENT_DOMSTRING (EvolSelectedString, "selected")
|
|
IMPLEMENT_DOMSTRING (EvolReplaceString, "replace")
|
|
|
|
//=======================================================================
|
|
//function : XmlMNaming_NamedShapeDriver
|
|
//purpose : Constructor
|
|
//=======================================================================
|
|
|
|
XmlMNaming_NamedShapeDriver::XmlMNaming_NamedShapeDriver
|
|
(const Handle(Message_Messenger)& theMessageDriver)
|
|
: XmlMDF_ADriver (theMessageDriver, NULL),
|
|
myShapeSet (Standard_False) // triangles mode
|
|
{}
|
|
|
|
//=======================================================================
|
|
//function : NewEmpty()
|
|
//purpose :
|
|
//=======================================================================
|
|
Handle(TDF_Attribute) XmlMNaming_NamedShapeDriver::NewEmpty () const
|
|
{
|
|
return (new TNaming_NamedShape());
|
|
}
|
|
|
|
//=======================================================================
|
|
//function : Paste()
|
|
//purpose : retrieval of TNaming_NamedShape
|
|
//=======================================================================
|
|
|
|
Standard_Boolean XmlMNaming_NamedShapeDriver::Paste
|
|
(const XmlObjMgt_Persistent& theSource,
|
|
const Handle(TDF_Attribute)& theTarget,
|
|
XmlObjMgt_RRelocationTable&) const
|
|
{
|
|
Handle(TNaming_NamedShape) aTarget =
|
|
Handle(TNaming_NamedShape)::DownCast(theTarget);
|
|
TDF_Label Label = aTarget -> Label();
|
|
TNaming_Builder aBld (Label);
|
|
|
|
// Get Version
|
|
Standard_Integer aVersion = 0;
|
|
const XmlObjMgt_Element& anElement = theSource;
|
|
XmlObjMgt_DOMString aVerString = anElement.getAttribute (::VersionString());
|
|
if (aVerString != NULL)
|
|
aVerString.GetInteger (aVersion);
|
|
|
|
// Get Evolution status
|
|
XmlObjMgt_DOMString aStatus = anElement.getAttribute (::StatusString());
|
|
TNaming_Evolution evol = EvolutionEnum (aStatus);
|
|
// apres creation Builder qui a mis la version a 1 :
|
|
aTarget -> SetVersion (aVersion);
|
|
|
|
const XmlObjMgt_Array1 OldPShapes (anElement, ::OldsString());
|
|
const XmlObjMgt_Array1 NewPShapes (anElement, ::NewsString());
|
|
if (NewPShapes.Length() == 0 && OldPShapes.Length() == 0)
|
|
return Standard_True;
|
|
|
|
TopoDS_Shape anOldShape;
|
|
TopoDS_Shape aNewShape;
|
|
BRepTools_ShapeSet& aShapeSet = (BRepTools_ShapeSet&) myShapeSet;
|
|
|
|
Standard_Integer lower = NewPShapes.Lower();
|
|
if (OldPShapes.Lower() < lower) lower = OldPShapes.Lower();
|
|
|
|
Standard_Integer upper = NewPShapes.Upper();
|
|
if (OldPShapes.Upper() > upper) upper = OldPShapes.Upper();
|
|
|
|
for (Standard_Integer i = upper; i >= lower; --i)
|
|
{
|
|
const XmlMNaming_Shape1 aNewPShape = NewPShapes.Value(i);
|
|
const XmlMNaming_Shape1 anOldPShape = OldPShapes.Value(i);
|
|
|
|
if ( evol != TNaming_PRIMITIVE && anOldPShape.Element() != NULL )
|
|
{
|
|
if (::doTranslate (anOldPShape, anOldShape, aShapeSet)) {
|
|
myMessageDriver->Send ("NamedShapeDriver: Error reading a shape from array", Message_Fail);
|
|
return Standard_False;
|
|
}
|
|
}
|
|
|
|
if (evol != TNaming_DELETE && aNewPShape.Element() != NULL )
|
|
{
|
|
if (::doTranslate (aNewPShape, aNewShape, aShapeSet)) {
|
|
myMessageDriver->Send ("NamedShapeDriver: Error reading a shape from array", Message_Fail);
|
|
return Standard_False;
|
|
}
|
|
}
|
|
|
|
switch (evol)
|
|
{
|
|
case TNaming_PRIMITIVE:
|
|
aBld.Generated(aNewShape);
|
|
break;
|
|
case TNaming_GENERATED:
|
|
aBld.Generated(anOldShape,aNewShape);
|
|
break;
|
|
case TNaming_MODIFY:
|
|
aBld.Modify(anOldShape,aNewShape);
|
|
break;
|
|
case TNaming_DELETE:
|
|
aBld.Delete(anOldShape);
|
|
break;
|
|
case TNaming_SELECTED:
|
|
aBld.Select(aNewShape, anOldShape);
|
|
break;
|
|
case TNaming_REPLACE:
|
|
aBld.Modify(anOldShape,aNewShape);
|
|
break; // for compatibility
|
|
// case TNaming_REPLACE:
|
|
// aBld.Replace(anOldShape,aNewShape);
|
|
// break;
|
|
default:
|
|
throw Standard_DomainError("TNaming_Evolution; enum term unknown");
|
|
}
|
|
anOldShape.Nullify();
|
|
aNewShape.Nullify();
|
|
}
|
|
return Standard_True;
|
|
}
|
|
|
|
//=======================================================================
|
|
//function : Paste()
|
|
//purpose : storage of TNaming_NamedShape
|
|
//=======================================================================
|
|
|
|
void XmlMNaming_NamedShapeDriver::Paste (const Handle(TDF_Attribute)& theSource,
|
|
XmlObjMgt_Persistent& theTarget,
|
|
XmlObjMgt_SRelocationTable&) const
|
|
{
|
|
//AGV XmlObjMgt_Document& aDoc =
|
|
//AGV (XmlObjMgt_Document&) theTarget.Element().getOwnerDocument();
|
|
XmlObjMgt_Document aDoc =
|
|
XmlObjMgt_Document (theTarget.Element().getOwnerDocument());
|
|
|
|
Handle(TNaming_NamedShape) aNamedShape =
|
|
Handle(TNaming_NamedShape)::DownCast(theSource);
|
|
TNaming_Evolution evol = aNamedShape->Evolution();
|
|
|
|
// Create arrays
|
|
Standard_Integer NbShapes = 0;
|
|
TNaming_Iterator SItr (aNamedShape);
|
|
while (SItr.More()) {
|
|
NbShapes++;
|
|
SItr.Next ();
|
|
}
|
|
|
|
BRepTools_ShapeSet& aShapeSet = (BRepTools_ShapeSet&) myShapeSet;
|
|
XmlObjMgt_Array1 OldPShapes (1,NbShapes), NewPShapes (1,NbShapes);
|
|
|
|
OldPShapes.CreateArrayElement (theTarget, ::OldsString());
|
|
NewPShapes.CreateArrayElement (theTarget, ::NewsString());
|
|
|
|
// Fill arrays
|
|
Standard_Integer i = 1;
|
|
TNaming_Iterator SIterator(aNamedShape);
|
|
while (SIterator.More())
|
|
{
|
|
const TopoDS_Shape& OldShape = SIterator.OldShape();
|
|
const TopoDS_Shape& NewShape = SIterator.NewShape();
|
|
|
|
if ( evol != TNaming_PRIMITIVE )
|
|
{
|
|
XmlMNaming_Shape1 anOldPShape (aDoc);
|
|
::doTranslate (OldShape, anOldPShape, aShapeSet);
|
|
OldPShapes.SetValue (i, anOldPShape.Element());
|
|
}
|
|
|
|
if (evol != TNaming_DELETE)
|
|
{
|
|
XmlMNaming_Shape1 aNewPShape (aDoc);
|
|
::doTranslate (NewShape, aNewPShape, aShapeSet);
|
|
NewPShapes.SetValue (i, aNewPShape.Element());
|
|
}
|
|
i++;
|
|
SIterator.Next();
|
|
}
|
|
|
|
theTarget.Element().setAttribute (::StatusString(), EvolutionString(evol));
|
|
Standard_Integer aVersion = aNamedShape -> Version();
|
|
if (aVersion != 0)
|
|
theTarget.Element().setAttribute (::VersionString(), aVersion);
|
|
}
|
|
|
|
//=======================================================================
|
|
//function : EvolutionEnum
|
|
//purpose : static
|
|
//=======================================================================
|
|
|
|
static const XmlObjMgt_DOMString& EvolutionString(const TNaming_Evolution i)
|
|
{
|
|
switch(i) {
|
|
case TNaming_PRIMITIVE : return ::EvolPrimitiveString();
|
|
case TNaming_GENERATED : return ::EvolGeneratedString();
|
|
case TNaming_MODIFY : return ::EvolModifyString();
|
|
case TNaming_DELETE : return ::EvolDeleteString();
|
|
case TNaming_SELECTED : return ::EvolSelectedString();
|
|
case TNaming_REPLACE : return ::EvolModifyString(); // case TNaming_REPLACE : return ::EvolReplaceString(); for compatibility
|
|
default:
|
|
throw Standard_DomainError("TNaming_Evolution; enum term unknown");
|
|
}
|
|
}
|
|
|
|
//=======================================================================
|
|
//function : EvolutionEnum
|
|
//purpose : static
|
|
//=======================================================================
|
|
|
|
static TNaming_Evolution EvolutionEnum (const XmlObjMgt_DOMString& theString)
|
|
{
|
|
TNaming_Evolution aResult = TNaming_PRIMITIVE;
|
|
if (theString.equals (::EvolPrimitiveString()) == Standard_False) {
|
|
if (theString.equals (::EvolGeneratedString()))
|
|
aResult = TNaming_GENERATED;
|
|
else if (theString.equals (::EvolModifyString()))
|
|
aResult = TNaming_MODIFY;
|
|
else if (theString.equals (::EvolDeleteString()))
|
|
aResult = TNaming_DELETE;
|
|
else if (theString.equals (::EvolSelectedString()))
|
|
aResult = TNaming_SELECTED;
|
|
else if (theString.equals (::EvolReplaceString()))
|
|
aResult = TNaming_MODIFY; // for compatibility //TNaming_REPLACE;
|
|
else
|
|
throw Standard_DomainError("TNaming_Evolution; string value without enum term equivalence");
|
|
}
|
|
return aResult;
|
|
}
|
|
|
|
//=======================================================================
|
|
//function : doTranslate
|
|
//purpose : shape storage to XML
|
|
//=======================================================================
|
|
|
|
static void doTranslate (const TopoDS_Shape& theShape,
|
|
XmlMNaming_Shape1& theResult,
|
|
BRepTools_ShapeSet& theShapeSet)
|
|
{
|
|
// Check for empty shape
|
|
if (theShape.IsNull()) return;
|
|
|
|
// Add to shape set both TShape and Location contained in theShape
|
|
const Standard_Integer aTShapeId = theShapeSet.Add (theShape);
|
|
const Standard_Integer aLocId =
|
|
theShapeSet.Locations().Index (theShape.Location());
|
|
|
|
// Fill theResult with shape parameters: TShape ID, Location, Orientation
|
|
theResult.SetShape (aTShapeId, aLocId, theShape.Orientation());
|
|
|
|
if (theShape.ShapeType() == TopAbs_VERTEX)
|
|
{
|
|
theResult.SetVertex(theShape);
|
|
}
|
|
}
|
|
|
|
//=======================================================================
|
|
//function : doTranslate
|
|
//purpose : shape retrieval from XML
|
|
//=======================================================================
|
|
|
|
static int doTranslate (const XmlMNaming_Shape1& thePShape,
|
|
TopoDS_Shape& theResult,
|
|
BRepTools_ShapeSet& theShapeSet)
|
|
{
|
|
const Standard_Integer aShapeId = thePShape.TShapeId();
|
|
|
|
// Read TShape and Orientation
|
|
if (aShapeId <= 0 || aShapeId > theShapeSet.NbShapes())
|
|
return 1;
|
|
theResult.TShape (theShapeSet.Shape(aShapeId).TShape());
|
|
theResult.Orientation (thePShape.Orientation());
|
|
theResult.Location (theShapeSet.Locations().Location (thePShape.LocId()), false);
|
|
|
|
return 0;
|
|
}
|
|
|
|
//=======================================================================
|
|
//function : ReadShapeSection
|
|
//purpose :
|
|
//=======================================================================
|
|
|
|
void XmlMNaming_NamedShapeDriver::ReadShapeSection (const XmlObjMgt_Element& theElement,
|
|
const Message_ProgressRange& theRange)
|
|
{
|
|
XmlObjMgt_Element anElement =
|
|
XmlObjMgt::FindChildByName (theElement, ::ShapesString());
|
|
if (anElement != NULL) {
|
|
for (LDOM_Node aNode = anElement.getFirstChild();
|
|
aNode != NULL;
|
|
aNode = anElement.getNextSibling())
|
|
{
|
|
if (aNode.getNodeType() == LDOM_Node::TEXT_NODE) {
|
|
LDOMString aData = aNode.getNodeValue();
|
|
std::stringstream aStream (std::string(aData.GetString()));
|
|
myShapeSet.Clear();
|
|
myShapeSet.Read (aStream, theRange);
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
//=======================================================================
|
|
//function : WriteShapeSection
|
|
//purpose :
|
|
//=======================================================================
|
|
|
|
void XmlMNaming_NamedShapeDriver::WriteShapeSection (XmlObjMgt_Element& theElement,
|
|
TDocStd_FormatVersion theStorageFormatVersion,
|
|
const Message_ProgressRange& theRange)
|
|
{
|
|
// Create "shapes" element and append it as child
|
|
XmlObjMgt_Document aDoc = theElement.getOwnerDocument();
|
|
XmlObjMgt_Element anElement = aDoc.createElement (::ShapesString());
|
|
theElement.appendChild (anElement);
|
|
|
|
// Add text to the "shapes" element
|
|
if (myShapeSet.NbShapes() > 0)
|
|
{
|
|
if (theStorageFormatVersion >= TDocStd_FormatVersion_VERSION_11)
|
|
{
|
|
myShapeSet.SetFormatNb(TopTools_FormatVersion_VERSION_3);
|
|
}
|
|
else
|
|
{
|
|
myShapeSet.SetFormatNb(TopTools_FormatVersion_VERSION_1);
|
|
}
|
|
|
|
LDOM_OSStream aStream (16 * 1024);
|
|
// ostrstream aStream;
|
|
// aStream.rdbuf() -> setbuf (0, 16380);
|
|
Message_ProgressScope aPS(theRange, "Writing shape section", 2);
|
|
myShapeSet.Write (aStream, aPS.Next());
|
|
if (!aPS.More())
|
|
return;
|
|
|
|
aStream << std::ends;
|
|
char * aStr = (char *)aStream.str();
|
|
LDOM_Text aText = aDoc.createTextNode (aStr);
|
|
delete [] aStr;
|
|
aText.SetValueClear(); // There are no characters '<' and '&' and like
|
|
// aStream.rdbuf() -> freeze(0); // release the buffer
|
|
anElement.appendChild (aText);
|
|
// Clear the shape set to avoid appending to it on the next write
|
|
BRepTools_ShapeSet& aShapeSet = (BRepTools_ShapeSet&) myShapeSet;
|
|
aShapeSet.Clear();
|
|
if (!aPS.More())
|
|
return;
|
|
aPS.Next();
|
|
}
|
|
}
|
|
|
|
//=======================================================================
|
|
//function : Clear
|
|
//purpose :
|
|
//=======================================================================
|
|
|
|
void XmlMNaming_NamedShapeDriver::Clear()
|
|
{
|
|
myShapeSet.Clear();
|
|
}
|