Files
opennurbs/opennurbs_object_history.cpp
2024-08-22 01:43:04 -07:00

3180 lines
71 KiB
C++

//
// Copyright (c) 1993-2022 Robert McNeel & Associates. All rights reserved.
// OpenNURBS, Rhinoceros, and Rhino3D are registered trademarks of Robert
// McNeel & Associates.
//
// THIS SOFTWARE IS PROVIDED "AS IS" WITHOUT EXPRESS OR IMPLIED WARRANTY.
// ALL IMPLIED WARRANTIES OF FITNESS FOR ANY PARTICULAR PURPOSE AND OF
// MERCHANTABILITY ARE HEREBY DISCLAIMED.
//
// For complete openNURBS copyright information see <http://www.opennurbs.org>.
//
////////////////////////////////////////////////////////////////
#include "opennurbs.h"
#if !defined(ON_COMPILING_OPENNURBS)
// This check is included in all opennurbs source .c and .cpp files to insure
// ON_COMPILING_OPENNURBS is defined when opennurbs source is compiled.
// When opennurbs source is being compiled, ON_COMPILING_OPENNURBS is defined
// and the opennurbs .h files alter what is declared and how it is declared.
#error ON_COMPILING_OPENNURBS must be defined when compiling opennurbs
#endif
class ON_Value
{
public:
// The VALUE_TYPE enum values must never be changed
// because the values are used to determine the parameter
// type during file reading. Additions can be made.
enum VALUE_TYPE
{
no_value_type = 0,
bool_value = 1,
int_value = 2,
double_value = 3,
color_value = 4,
point_value = 5,
vector_value = 6,
xform_value = 7,
string_value = 8,
objref_value = 9,
geometry_value = 10,
uuid_value = 11,
point_on_object_value = 12,
polyedge_value = 13,
subd_edge_chain_value = 14,
// each value type must have a case in ON_Value::CreateValue().
force_32bit_enum = 0xFFFFFFFF
};
static
ON_Value* CreateValue( int value_type );
void Report(
ON_TextLog& text_log
) const;
// The valid id is a nonzero integer the developer
// assigns to this value. Developers are responsible
// for ensuring the
int m_value_id = -1;
const VALUE_TYPE m_value_type;
ON_Value(VALUE_TYPE);
ON_Value(const ON_Value& src);
virtual ~ON_Value();
virtual ON_Value* Duplicate() const=0;
virtual int Count() const=0;
virtual bool ReadHelper(ON_BinaryArchive& )=0;
virtual bool WriteHelper(ON_BinaryArchive& ) const=0;
virtual bool ReportHelper(ON_TextLog& ) const=0;
virtual int GetBools( const bool*& ) const;
virtual int GetInts( const int*& ) const;
virtual int GetColors( const ON_Color*& ) const;
virtual int GetDoubles( const double*& ) const;
virtual int Get3dPoints( const ON_3dPoint*& ) const;
virtual int Get3dVectors( const ON_3dVector*& ) const;
virtual int GetXforms( const ON_Xform*& ) const;
virtual int GetUuids( const ON_UUID*& ) const;
virtual int GetObjRefs( ON_ClassArray<ON_ObjRef>& ) const;
virtual int GetGeometryPointers( const ON_Geometry* const*& ) const;
virtual int GetSubDEdgeChainPointers(const ON_SubDEdgeChain* const*&) const;
virtual int GetStrings( ON_ClassArray<ON_wString>& ) const;
virtual int GetPolyEdgePointers(ON_ClassArray<ON_PolyEdgeHistory>&) const;
private:
// no implementation
ON_Value() = delete;
ON_Value& operator=(const ON_Value&) = delete;
};
ON_Value::ON_Value( ON_Value::VALUE_TYPE value_type )
: m_value_type(value_type)
{}
ON_Value::ON_Value(const ON_Value& src)
: m_value_id(src.m_value_id)
, m_value_type(src.m_value_type)
{}
ON_Value::~ON_Value()
{}
// base class virtuals do nothing.
int ON_Value::GetBools( const bool*& ) const {return 0;}
int ON_Value::GetInts( const int*& ) const {return 0;}
int ON_Value::GetColors( const ON_Color*& ) const {return 0;}
int ON_Value::GetDoubles( const double*& ) const {return 0;}
int ON_Value::Get3dPoints( const ON_3dPoint*& ) const {return 0;}
int ON_Value::Get3dVectors( const ON_3dVector*& ) const {return 0;}
int ON_Value::GetXforms( const ON_Xform*& ) const {return 0;}
int ON_Value::GetUuids( const ON_UUID*& ) const {return 0;}
int ON_Value::GetObjRefs( ON_ClassArray<ON_ObjRef>& ) const {return 0;}
int ON_Value::GetGeometryPointers( const ON_Geometry* const*& ) const {return 0;}
int ON_Value::GetSubDEdgeChainPointers(const ON_SubDEdgeChain* const*&) const { return 0; }
int ON_Value::GetStrings( ON_ClassArray<ON_wString>& ) const {return 0;}
int ON_Value::GetPolyEdgePointers(ON_ClassArray<ON_PolyEdgeHistory>&) const { return 0; }
class ON_DummyValue : public ON_Value
{
public:
ON_DummyValue();
~ON_DummyValue();
ON_Value* Duplicate() const;
int Count() const;
bool ReadHelper(ON_BinaryArchive& );
bool WriteHelper(ON_BinaryArchive& ) const;
bool ReportHelper(ON_TextLog& ) const;
};
ON_DummyValue::ON_DummyValue() : ON_Value(ON_Value::no_value_type)
{
}
ON_DummyValue::~ON_DummyValue()
{
}
ON_Value* ON_DummyValue::Duplicate() const {return 0;}
int ON_DummyValue::Count() const {return 0;}
bool ON_DummyValue::ReadHelper(ON_BinaryArchive& ) {return 0;}
bool ON_DummyValue::WriteHelper(ON_BinaryArchive& ) const {return 0;}
bool ON_DummyValue::ReportHelper(ON_TextLog& ) const {return 0;}
///////////////////////////////////////////////////////////////////////
//
// ON_BoolValue saves bool values in the ON_HistoryRecord::m_value[] array
//
class ON_BoolValue : public ON_Value
{
public:
ON_BoolValue();
~ON_BoolValue();
ON_SimpleArray<bool> m_value;
// virtual
class ON_Value* Duplicate() const;
// virtual
int Count() const;
// virtual
bool ReadHelper(ON_BinaryArchive& archive );
// virtual
bool WriteHelper(ON_BinaryArchive& archive ) const;
// virtual
bool ReportHelper(ON_TextLog& text_log ) const;
// virtual
int GetBools( const bool*& b ) const;
};
ON_BoolValue::ON_BoolValue()
: ON_Value(ON_Value::bool_value)
{
}
ON_BoolValue::~ON_BoolValue()
{
}
// virtual
class ON_Value* ON_BoolValue::Duplicate() const
{
return new ON_BoolValue(*this);
}
// virtual
int ON_BoolValue::Count() const
{
return m_value.Count();
}
// virtual
bool ON_BoolValue::ReadHelper(ON_BinaryArchive& archive )
{
return archive.ReadArray(m_value);
}
// virtual
bool ON_BoolValue::WriteHelper(ON_BinaryArchive& archive ) const
{
return archive.WriteArray(m_value);
}
// virtual
bool ON_BoolValue::ReportHelper(ON_TextLog& text_log ) const
{
int i, count = m_value.Count();
text_log.Print("bool value\n");
text_log.PushIndent();
for ( i = 0; i < count; i++ )
{
text_log.Print(m_value[i]?"true":"false");
}
text_log.PopIndent();
return true;
}
// virtual
int ON_BoolValue::GetBools( const bool*& b ) const
{
b = m_value.Array();
return m_value.Count();
}
///////////////////////////////////////////////////////////////////////
//
// ON_IntValue saves int values in the ON_HistoryRecord::m_value[] array
//
class ON_IntValue : public ON_Value
{
public:
ON_IntValue();
~ON_IntValue();
ON_SimpleArray<int> m_value;
// virtual
class ON_Value* Duplicate() const;
// virtual
int Count() const;
// virtual
bool ReadHelper(ON_BinaryArchive& archive );
// virtual
bool WriteHelper(ON_BinaryArchive& archive ) const;
// virtual
bool ReportHelper(ON_TextLog& text_log ) const;
// virtual
int GetInts( const int*& b ) const;
};
ON_IntValue::ON_IntValue()
: ON_Value(ON_Value::int_value)
{
}
ON_IntValue::~ON_IntValue()
{
}
// virtual
class ON_Value* ON_IntValue::Duplicate() const
{
return new ON_IntValue(*this);
}
// virtual
int ON_IntValue::Count() const
{
return m_value.Count();
}
// virtual
bool ON_IntValue::ReadHelper(ON_BinaryArchive& archive )
{
return archive.ReadArray(m_value);
}
// virtual
bool ON_IntValue::WriteHelper(ON_BinaryArchive& archive ) const
{
return archive.WriteArray(m_value);
}
// virtual
bool ON_IntValue::ReportHelper(ON_TextLog& text_log ) const
{
int i, count = m_value.Count();
text_log.Print("integer value\n");
text_log.PushIndent();
for ( i = 0; i < count; i++ )
{
text_log.Print("%d",m_value[i]);
}
text_log.PopIndent();
return true;
}
// virtual
int ON_IntValue::GetInts( const int*& b ) const
{
b = m_value.Array();
return m_value.Count();
}
///////////////////////////////////////////////////////////////////////
//
// ON_DoubleValue saves bool values in the ON_HistoryRecord::m_value[] array
//
class ON_DoubleValue : public ON_Value
{
public:
ON_DoubleValue();
~ON_DoubleValue();
ON_SimpleArray<double> m_value;
// virtual
class ON_Value* Duplicate() const;
// virtual
int Count() const;
// virtual
bool ReadHelper(ON_BinaryArchive& archive );
// virtual
bool WriteHelper(ON_BinaryArchive& archive ) const;
// virtual
bool ReportHelper(ON_TextLog& text_log ) const;
// virtual
int GetDoubles( const double*& a ) const;
};
ON_DoubleValue::ON_DoubleValue()
: ON_Value(ON_Value::double_value)
{
}
ON_DoubleValue::~ON_DoubleValue()
{
}
// virtual
class ON_Value* ON_DoubleValue::Duplicate() const
{
return new ON_DoubleValue(*this);
}
// virtual
int ON_DoubleValue::Count() const
{
return m_value.Count();
}
// virtual
bool ON_DoubleValue::ReadHelper(ON_BinaryArchive& archive )
{
return archive.ReadArray(m_value);
}
// virtual
bool ON_DoubleValue::WriteHelper(ON_BinaryArchive& archive ) const
{
return archive.WriteArray(m_value);
}
// virtual
bool ON_DoubleValue::ReportHelper(ON_TextLog& text_log ) const
{
int i, count = m_value.Count();
text_log.Print("number value\n");
text_log.PushIndent();
for ( i = 0; i < count; i++ )
{
text_log.Print(m_value[i]);
}
text_log.PopIndent();
return true;
}
// virtual
int ON_DoubleValue::GetDoubles( const double*& a ) const
{
a = m_value.Array();
return m_value.Count();
}
///////////////////////////////////////////////////////////////////////
//
// ON_PointValue saves bool values in the ON_HistoryRecord::m_value[] array
//
class ON_PointValue : public ON_Value
{
public:
ON_PointValue();
~ON_PointValue();
ON_SimpleArray<ON_3dPoint> m_value;
// virtual
class ON_Value* Duplicate() const;
// virtual
int Count() const;
// virtual
bool ReadHelper(ON_BinaryArchive& archive );
// virtual
bool WriteHelper(ON_BinaryArchive& archive ) const;
// virtual
bool ReportHelper(ON_TextLog& text_log ) const;
// virtual
int Get3dPoints( const ON_3dPoint*& a ) const;
};
ON_PointValue::ON_PointValue()
: ON_Value(ON_Value::point_value)
{
}
ON_PointValue::~ON_PointValue()
{
}
// virtual
class ON_Value* ON_PointValue::Duplicate() const
{
return new ON_PointValue(*this);
}
// virtual
int ON_PointValue::Count() const
{
return m_value.Count();
}
// virtual
bool ON_PointValue::ReadHelper(ON_BinaryArchive& archive )
{
return archive.ReadArray(m_value);
}
// virtual
bool ON_PointValue::WriteHelper(ON_BinaryArchive& archive ) const
{
return archive.WriteArray(m_value);
}
// virtual
bool ON_PointValue::ReportHelper(ON_TextLog& text_log ) const
{
int i, count = m_value.Count();
text_log.Print("point value\n");
text_log.PushIndent();
for ( i = 0; i < count; i++ )
{
text_log.Print(m_value[i]);
}
text_log.PopIndent();
return true;
}
// virtual
int ON_PointValue::Get3dPoints( const ON_3dPoint*& a ) const
{
a = m_value.Array();
return m_value.Count();
}
///////////////////////////////////////////////////////////////////////
//
// ON_VectorValue saves bool values in the ON_HistoryRecord::m_value[] array
//
class ON_VectorValue : public ON_Value
{
public:
ON_VectorValue();
~ON_VectorValue();
ON_SimpleArray<ON_3dVector> m_value;
// virtual
class ON_Value* Duplicate() const;
// virtual
int Count() const;
// virtual
bool ReadHelper(ON_BinaryArchive& archive );
// virtual
bool WriteHelper(ON_BinaryArchive& archive ) const;
// virtual
bool ReportHelper(ON_TextLog& text_log ) const;
// virtual
int Get3dVectors( const ON_3dVector*& a ) const;
};
ON_VectorValue::ON_VectorValue()
: ON_Value(ON_Value::vector_value)
{
}
ON_VectorValue::~ON_VectorValue()
{
}
// virtual
class ON_Value* ON_VectorValue::Duplicate() const
{
return new ON_VectorValue(*this);
}
// virtual
int ON_VectorValue::Count() const
{
return m_value.Count();
}
// virtual
bool ON_VectorValue::ReadHelper(ON_BinaryArchive& archive )
{
return archive.ReadArray(m_value);
}
// virtual
bool ON_VectorValue::WriteHelper(ON_BinaryArchive& archive ) const
{
return archive.WriteArray(m_value);
}
// virtual
bool ON_VectorValue::ReportHelper(ON_TextLog& text_log ) const
{
text_log.Print("vector value\n");
text_log.PushIndent();
int i, count = m_value.Count();
for ( i = 0; i < count; i++ )
{
text_log.Print(m_value[i]);
}
text_log.PopIndent();
return true;
}
// virtual
int ON_VectorValue::Get3dVectors( const ON_3dVector*& a ) const
{
a = m_value.Array();
return m_value.Count();
}
///////////////////////////////////////////////////////////////////////
//
// ON_XformValue saves bool values in the ON_HistoryRecord::m_value[] array
//
class ON_XformValue : public ON_Value
{
public:
ON_XformValue();
~ON_XformValue();
ON_SimpleArray<ON_Xform> m_value;
// virtual
class ON_Value* Duplicate() const;
// virtual
int Count() const;
// virtual
bool ReadHelper(ON_BinaryArchive& archive );
// virtual
bool WriteHelper(ON_BinaryArchive& archive ) const;
// virtual
bool ReportHelper(ON_TextLog& text_log ) const;
// virtual
int GetXforms( const ON_Xform*& a ) const;
};
ON_XformValue::ON_XformValue()
: ON_Value(ON_Value::xform_value)
{
}
ON_XformValue::~ON_XformValue()
{
}
// virtual
class ON_Value* ON_XformValue::Duplicate() const
{
return new ON_XformValue(*this);
}
// virtual
int ON_XformValue::Count() const
{
return m_value.Count();
}
// virtual
bool ON_XformValue::ReadHelper(ON_BinaryArchive& archive )
{
return archive.ReadArray(m_value);
}
// virtual
bool ON_XformValue::WriteHelper(ON_BinaryArchive& archive ) const
{
return archive.WriteArray(m_value);
}
// virtual
bool ON_XformValue::ReportHelper(ON_TextLog& text_log ) const
{
text_log.Print("xform value\n");
text_log.PushIndent();
int i, count = m_value.Count();
for ( i = 0; i < count; i++ )
{
text_log.Print(m_value[i]);
}
text_log.PopIndent();
return true;
}
// virtual
int ON_XformValue::GetXforms( const ON_Xform*& a ) const
{
a = m_value.Array();
return m_value.Count();
}
///////////////////////////////////////////////////////////////////////
//
// ON_ColorValue saves bool values in the ON_HistoryRecord::m_value[] array
//
class ON_ColorValue : public ON_Value
{
public:
ON_ColorValue();
~ON_ColorValue();
ON_SimpleArray<ON_Color> m_value;
// virtual
class ON_Value* Duplicate() const;
// virtual
int Count() const;
// virtual
bool ReadHelper(ON_BinaryArchive& archive );
// virtual
bool WriteHelper(ON_BinaryArchive& archive ) const;
// virtual
bool ReportHelper(ON_TextLog& text_log ) const;
// virtual
int GetColors( const ON_Color*& a ) const;
};
ON_ColorValue::ON_ColorValue()
: ON_Value(ON_Value::color_value)
{
}
ON_ColorValue::~ON_ColorValue()
{
}
// virtual
class ON_Value* ON_ColorValue::Duplicate() const
{
return new ON_ColorValue(*this);
}
// virtual
int ON_ColorValue::Count() const
{
return m_value.Count();
}
// virtual
bool ON_ColorValue::ReadHelper(ON_BinaryArchive& archive )
{
return archive.ReadArray(m_value);
}
// virtual
bool ON_ColorValue::WriteHelper(ON_BinaryArchive& archive ) const
{
return archive.WriteArray(m_value);
}
// virtual
bool ON_ColorValue::ReportHelper(ON_TextLog& text_log ) const
{
ON_Color c;
text_log.Print("color value\n");
text_log.PushIndent();
int i, count = m_value.Count();
for ( i = 0; i < count; i++ )
{
c = m_value[i];
text_log.Print("rbg(%d,%d,%d)",c.Red(),c.Green(),c.Blue());
}
text_log.PopIndent();
return true;
}
// virtual
int ON_ColorValue::GetColors( const ON_Color*& a ) const
{
a = m_value.Array();
return m_value.Count();
}
///////////////////////////////////////////////////////////////////////
//
// ON_UuidValue saves bool values in the ON_HistoryRecord::m_value[] array
//
class ON_UuidValue : public ON_Value
{
public:
ON_UuidValue();
~ON_UuidValue();
ON_SimpleArray<ON_UUID> m_value;
// virtual
class ON_Value* Duplicate() const;
// virtual
int Count() const;
// virtual
bool ReadHelper(ON_BinaryArchive& archive );
// virtual
bool WriteHelper(ON_BinaryArchive& archive ) const;
// virtual
bool ReportHelper(ON_TextLog& text_log ) const;
// virtual
int GetUuids( const ON_UUID*& a ) const;
};
ON_UuidValue::ON_UuidValue()
: ON_Value(ON_Value::uuid_value)
{
}
ON_UuidValue::~ON_UuidValue()
{
}
// virtual
class ON_Value* ON_UuidValue::Duplicate() const
{
return new ON_UuidValue(*this);
}
// virtual
int ON_UuidValue::Count() const
{
return m_value.Count();
}
// virtual
bool ON_UuidValue::ReadHelper(ON_BinaryArchive& archive )
{
return archive.ReadArray(m_value);
}
// virtual
bool ON_UuidValue::WriteHelper(ON_BinaryArchive& archive ) const
{
return archive.WriteArray(m_value);
}
// virtual
bool ON_UuidValue::ReportHelper(ON_TextLog& text_log ) const
{
text_log.Print("uuid value\n");
text_log.PushIndent();
int i, count = m_value.Count();
for ( i = 0; i < count; i++ )
{
text_log.Print(m_value[i]);
}
text_log.PopIndent();
return true;
}
// virtual
int ON_UuidValue::GetUuids( const ON_UUID*& a ) const
{
a = m_value.Array();
return m_value.Count();
}
///////////////////////////////////////////////////////////////////////
//
// ON_StringValue saves string values in the ON_HistoryRecord::m_value[] array
//
class ON_StringValue : public ON_Value
{
public:
ON_StringValue();
~ON_StringValue();
ON_ClassArray<ON_wString> m_value;
// virtual
class ON_Value* Duplicate() const;
// virtual
int Count() const;
// virtual
bool ReadHelper(ON_BinaryArchive& archive );
// virtual
bool WriteHelper(ON_BinaryArchive& archive ) const;
// virtual
bool ReportHelper(ON_TextLog& text_log ) const;
// virtual
int GetStrings( ON_ClassArray<ON_wString>& s ) const;
};
ON_StringValue::ON_StringValue()
: ON_Value(ON_Value::string_value)
{
}
ON_StringValue::~ON_StringValue()
{
}
// virtual
class ON_Value* ON_StringValue::Duplicate() const
{
return new ON_StringValue(*this);
}
// virtual
int ON_StringValue::Count() const
{
return m_value.Count();
}
// virtual
bool ON_StringValue::ReadHelper(ON_BinaryArchive& archive )
{
return archive.ReadArray(m_value);
}
// virtual
bool ON_StringValue::WriteHelper(ON_BinaryArchive& archive ) const
{
return archive.WriteArray(m_value);
}
// virtual
bool ON_StringValue::ReportHelper(ON_TextLog& text_log ) const
{
text_log.Print("string value\n");
text_log.PushIndent();
int i, count = m_value.Count();
for ( i = 0; i < count; i++ )
{
text_log.Print(m_value[i]);
}
text_log.PopIndent();
return true;
}
// virtual
int ON_StringValue::GetStrings( ON_ClassArray<ON_wString>& s ) const
{
s = m_value;
return m_value.Count();
}
///////////////////////////////////////////////////////////////////////
//
// ON_ObjRefValue saves objref values in the ON_HistoryRecord::m_value[] array
//
class ON_ObjRefValue : public ON_Value
{
public:
ON_ObjRefValue();
~ON_ObjRefValue();
ON_ClassArray<ON_ObjRef> m_value;
// virtual
class ON_Value* Duplicate() const;
// virtual
int Count() const;
// virtual
bool ReadHelper(ON_BinaryArchive& archive );
// virtual
bool WriteHelper(ON_BinaryArchive& archive ) const;
// virtual
bool ReportHelper(ON_TextLog& text_log ) const;
// virtual
int GetObjRefs( ON_ClassArray<ON_ObjRef>& oref ) const;
};
ON_ObjRefValue::ON_ObjRefValue()
: ON_Value(ON_Value::objref_value)
{
}
ON_ObjRefValue::~ON_ObjRefValue()
{
}
// virtual
class ON_Value* ON_ObjRefValue::Duplicate() const
{
return new ON_ObjRefValue(*this);
}
// virtual
int ON_ObjRefValue::Count() const
{
return m_value.Count();
}
// virtual
bool ON_ObjRefValue::ReadHelper(ON_BinaryArchive& archive )
{
return archive.ReadArray(m_value);
}
// virtual
bool ON_ObjRefValue::WriteHelper(ON_BinaryArchive& archive ) const
{
return archive.WriteArray(m_value);
}
// virtual
bool ON_ObjRefValue::ReportHelper(ON_TextLog& text_log ) const
{
text_log.Print("objref value\n");
text_log.PushIndent();
int i, count = m_value.Count();
for ( i = 0; i < count; i++ )
{
text_log.Print("object id: ");
text_log.Print(m_value[i].m_uuid);
text_log.Print("\n");
}
text_log.PopIndent();
return true;
}
// virtual
int ON_ObjRefValue::GetObjRefs( ON_ClassArray<ON_ObjRef>& s ) const
{
s = m_value;
return m_value.Count();
}
///////////////////////////////////////////////////////////////////////
//
// ON_GeometryValue saves geometry values in the ON_HistoryRecord::m_value[] array
//
class ON_GeometryValue : public ON_Value
{
public:
ON_GeometryValue();
~ON_GeometryValue();
ON_GeometryValue(const ON_GeometryValue& src);
ON_GeometryValue& operator=(const ON_GeometryValue& src);
ON_SimpleArray<ON_Geometry*> m_value;
// virtual
class ON_Value* Duplicate() const;
// virtual
int Count() const;
// virtual
bool ReadHelper(ON_BinaryArchive& archive );
// virtual
bool WriteHelper(ON_BinaryArchive& archive ) const;
// virtual
bool ReportHelper(ON_TextLog& text_log ) const;
// virtual
int GetGeometryPointers( const ON_Geometry* const*& ) const;
};
ON_GeometryValue::ON_GeometryValue()
: ON_Value(ON_Value::geometry_value)
{
}
ON_GeometryValue::~ON_GeometryValue()
{
int i, count = m_value.Count();
for ( i = 0; i < count; i++ )
{
ON_Geometry* p = m_value[i];
m_value[i] = 0;
if (p)
{
delete p;
}
}
}
ON_GeometryValue::ON_GeometryValue(const ON_GeometryValue& src) : ON_Value(src)
{
*this = src;
}
ON_GeometryValue& ON_GeometryValue::operator=(const ON_GeometryValue& src)
{
if ( this != &src )
{
int i, count = m_value.Count();
for ( i = 0; i < count; i++ )
{
ON_Geometry* p = m_value[i];
m_value[i] = 0;
if (p)
{
delete p;
}
}
m_value.Destroy();
m_value_id = src.m_value_id;
count = src.m_value.Count();
m_value.Reserve(count);
for ( i = 0; i < count; i++ )
{
const ON_Geometry* src_ptr = src.m_value[i];
if ( !src_ptr )
continue;
ON_Geometry* ptr = src_ptr->Duplicate();
if ( ptr )
m_value.Append(ptr);
}
}
return *this;
}
// virtual
class ON_Value* ON_GeometryValue::Duplicate() const
{
return new ON_GeometryValue(*this);
}
// virtual
int ON_GeometryValue::Count() const
{
return m_value.Count();
}
// virtual
bool ON_GeometryValue::ReadHelper(ON_BinaryArchive& archive )
{
int i, count = m_value.Count();
for ( i = 0; i < count; i++ )
{
delete m_value[i];
}
m_value.SetCount(0);
int major_version = 0;
int minor_version = 0;
bool rc = archive.BeginRead3dmChunk(TCODE_ANONYMOUS_CHUNK,&major_version,&minor_version);
if (!rc)
return false;
for(;;)
{
rc = archive.ReadInt(&count);
if (!rc) break;
m_value.Reserve(count);
for( i = 0; i < count && rc; i++ )
{
ON_Object* p=0;
rc = archive.ReadObject(&p) > 0;
if (rc)
{
ON_Geometry* g = ON_Geometry::Cast(p);
if (g)
{
p = 0;
m_value.Append(g);
}
}
if ( p )
delete p;
}
if (!rc) break;
break;
}
if ( !archive.EndRead3dmChunk() )
rc = false;
return rc;
}
// virtual
bool ON_GeometryValue::WriteHelper(ON_BinaryArchive& archive ) const
{
bool rc = archive.BeginWrite3dmChunk(TCODE_ANONYMOUS_CHUNK,1,0);
if (!rc)
return false;
for(;;)
{
rc = archive.WriteInt(m_value.Count());
if (!rc) break;
int i, count = m_value.Count();
for( i = 0; i < count && rc; i++ )
{
rc = archive.WriteObject(m_value[i]);
}
if (!rc) break;
break;
}
if ( !archive.EndWrite3dmChunk() )
rc = false;
return rc;
}
// virtual
bool ON_GeometryValue::ReportHelper(ON_TextLog& text_log ) const
{
text_log.Print("geometry value\n");
text_log.PushIndent();
int i, count = m_value.Count();
for ( i = 0; i < count; i++ )
{
const ON_Geometry* p = m_value[i];
if ( p )
p->Dump(text_log);
}
text_log.PopIndent();
return true;
}
// virtual
int ON_GeometryValue::GetGeometryPointers( const ON_Geometry* const*&a ) const
{
a = m_value.Array();
return m_value.Count();
}
///////////////////////////////////////////////////////////////////////
//
// ON_PolyEdgeHistoryValue saves geometry values in the ON_HistoryRecord::m_value[] array
//
class ON_PolyEdgeHistoryValue : public ON_Value
{
public:
ON_PolyEdgeHistoryValue();
~ON_PolyEdgeHistoryValue();
ON_ClassArray<ON_PolyEdgeHistory> m_value;
// virtual
class ON_Value* Duplicate() const;
// virtual
int Count() const;
// virtual
bool ReadHelper(ON_BinaryArchive& archive );
// virtual
bool WriteHelper(ON_BinaryArchive& archive ) const;
// virtual
bool ReportHelper(ON_TextLog& text_log ) const;
// virtual
int GetPolyEdgePointers( ON_ClassArray<ON_PolyEdgeHistory>& ) const;
};
ON_PolyEdgeHistoryValue::ON_PolyEdgeHistoryValue()
: ON_Value(ON_Value::polyedge_value)
{
}
ON_PolyEdgeHistoryValue::~ON_PolyEdgeHistoryValue()
{
m_value.Destroy();
}
//ON_PolyEdgeHistoryValue::ON_PolyEdgeHistoryValue(const ON_PolyEdgeHistoryValue& src) : ON_Value(src)
//{
// *this = src;
//}
//
//ON_PolyEdgeHistoryValue& ON_PolyEdgeHistoryValue::operator=(const ON_PolyEdgeHistoryValue& src)
//{
// if ( this != &src )
// {
// int i, count = m_value.Count();
// for ( i = 0; i < count; i++ )
// {
// ON_Geometry* p = m_value[i];
// m_value[i] = 0;
// if (p)
// {
// delete p;
// }
// }
// m_value.Destroy();
//
// m_value_id = src.m_value_id;
//
// count = src.m_value.Count();
// m_value.Reserve(count);
// for ( i = 0; i < count; i++ )
// {
// const ON_Geometry* src_ptr = src.m_value[i];
// if ( !src_ptr )
// continue;
// ON_Geometry* ptr = src_ptr->Duplicate();
// if ( ptr )
// m_value.Append(ptr);
// }
// }
// return *this;
//}
// virtual
class ON_Value* ON_PolyEdgeHistoryValue::Duplicate() const
{
return new ON_PolyEdgeHistoryValue(*this);
}
// virtual
int ON_PolyEdgeHistoryValue::Count() const
{
return m_value.Count();
}
// virtual
bool ON_PolyEdgeHistoryValue::ReadHelper(ON_BinaryArchive& archive )
{
m_value.Destroy();
int major_version = 0;
int minor_version = 0;
bool rc = archive.BeginRead3dmChunk(TCODE_ANONYMOUS_CHUNK,&major_version,&minor_version);
if (!rc)
return false;
for(;;)
{
int count = 0;
rc = archive.ReadInt(&count);
if (!rc) break;
m_value.Reserve(count);
for( int i = 0; i < count && rc; i++ )
{
if ( !m_value.AppendNew().Read(archive) )
{
m_value.Destroy();
rc = false;
break;
}
}
if (!rc) break;
break;
}
if ( !archive.EndRead3dmChunk() )
rc = false;
return rc;
}
// virtual
bool ON_PolyEdgeHistoryValue::WriteHelper(ON_BinaryArchive& archive ) const
{
bool rc = archive.BeginWrite3dmChunk(TCODE_ANONYMOUS_CHUNK,1,0);
if (!rc)
return false;
for(;;)
{
rc = archive.WriteInt(m_value.Count());
if (!rc) break;
int i, count = m_value.Count();
for( i = 0; i < count && rc; i++ )
{
rc = m_value[i].Write(archive);
}
if (!rc) break;
break;
}
if ( !archive.EndWrite3dmChunk() )
rc = false;
return rc;
}
// virtual
bool ON_PolyEdgeHistoryValue::ReportHelper(ON_TextLog& text_log ) const
{
text_log.Print("polyedge value\n");
text_log.PushIndent();
int i, count = m_value.Count();
for ( i = 0; i < count; i++ )
{
m_value[i].Dump(text_log);
}
text_log.PopIndent();
return true;
}
// virtual
int ON_PolyEdgeHistoryValue::GetPolyEdgePointers( ON_ClassArray<ON_PolyEdgeHistory>& a ) const
{
a = m_value;
return m_value.Count();
}
///////////////////////////////////////////////////////////////////////
//
// ON_SubDEdgeChainHistoryValue saves geometry values in the ON_HistoryRecord::m_value[] array
//
class ON_SubDEdgeChainHistoryValue : public ON_Value
{
public:
ON_SubDEdgeChainHistoryValue();
~ON_SubDEdgeChainHistoryValue();
ON_SubDEdgeChainHistoryValue(const ON_SubDEdgeChainHistoryValue&);
ON_SubDEdgeChainHistoryValue& operator=(const ON_SubDEdgeChainHistoryValue&);
ON_SimpleArray<ON_SubDEdgeChain*> m_value;
class ON_Value* Duplicate() const override;
int Count() const override;
bool ReadHelper(ON_BinaryArchive& archive) override;
bool WriteHelper(ON_BinaryArchive& archive) const override;
bool ReportHelper(ON_TextLog& text_log) const override;
int GetSubDEdgeChainPointers(const ON_SubDEdgeChain* const*&) const override;
};
ON_SubDEdgeChainHistoryValue::ON_SubDEdgeChainHistoryValue()
: ON_Value(ON_Value::subd_edge_chain_value)
{
}
ON_SubDEdgeChainHistoryValue::~ON_SubDEdgeChainHistoryValue()
{
int i, count = m_value.Count();
for (i = 0; i < count; i++)
{
ON_SubDEdgeChain* p = m_value[i];
if (nullptr != p)
{
m_value[i] = nullptr;
delete p;
}
}
}
ON_SubDEdgeChainHistoryValue::ON_SubDEdgeChainHistoryValue(const ON_SubDEdgeChainHistoryValue& src) : ON_Value(src)
{
*this = src;
}
ON_SubDEdgeChainHistoryValue& ON_SubDEdgeChainHistoryValue::operator=(const ON_SubDEdgeChainHistoryValue& src)
{
if (this != &src)
{
int i, count = m_value.Count();
for (i = 0; i < count; i++)
{
ON_SubDEdgeChain* p = m_value[i];
if (nullptr != p)
{
m_value[i] = nullptr;
delete p;
}
}
m_value.Destroy();
m_value_id = src.m_value_id;
count = src.m_value.Count();
m_value.Reserve(count);
for (i = 0; i < count; i++)
{
const ON_SubDEdgeChain* src_ptr = src.m_value[i];
if (!src_ptr)
continue;
ON_SubDEdgeChain* ptr = new ON_SubDEdgeChain(*src_ptr);
if (ptr)
m_value.Append(ptr);
}
}
return *this;
}
// virtual
class ON_Value* ON_SubDEdgeChainHistoryValue::Duplicate() const
{
return new ON_SubDEdgeChainHistoryValue(*this);
}
// virtual
int ON_SubDEdgeChainHistoryValue::Count() const
{
return m_value.Count();
}
// virtual
bool ON_SubDEdgeChainHistoryValue::ReadHelper(ON_BinaryArchive& archive)
{
m_value.Destroy();
int chunk_version = 0;
if (false == archive.BeginRead3dmAnonymousChunk(&chunk_version))
return false;
bool rc = false;
for (;;)
{
if (chunk_version < 1)
break;
int count = 0;
if (false == archive.ReadInt(&count))
break;
m_value.Reserve(count);
for (int i = 0; i < count; i++)
{
ON_SubDEdgeChain* c = new ON_SubDEdgeChain();
if (false == c->Read(archive))
break;
m_value.Append(c);
}
if (count == m_value.Count())
rc = true;
else
m_value.Destroy();
break;
}
if (!archive.EndRead3dmChunk())
rc = false;
return rc;
}
// virtual
bool ON_SubDEdgeChainHistoryValue::WriteHelper(ON_BinaryArchive& archive) const
{
if (false == archive.BeginWrite3dmAnonymousChunk(1))
return false;
bool rc = false;
for (;;)
{
int count = m_value.Count();
for (int i = 0; i < count; ++i)
{
if (nullptr == m_value[i])
count = 0;
}
if (false == archive.WriteInt(count))
break;
rc = true;
for (int i = 0; i < count && rc; i++)
rc = m_value[i]->Write(archive);
break;
}
if (!archive.EndWrite3dmChunk())
rc = false;
return rc;
}
// virtual
bool ON_SubDEdgeChainHistoryValue::ReportHelper(ON_TextLog& text_log) const
{
text_log.Print("SubD edge chain value\n");
text_log.PushIndent();
int i, count = m_value.Count();
for (i = 0; i < count; i++)
{
if( nullptr != m_value[i])
m_value[i]->Dump(text_log);
}
text_log.PopIndent();
return true;
}
// virtual
int ON_SubDEdgeChainHistoryValue::GetSubDEdgeChainPointers(const ON_SubDEdgeChain* const*& a) const
{
a = m_value.Array();
return m_value.Count();
}
///////////////////////////////////////////////////////////////////////
//
// static
ON_Value* ON_Value::CreateValue( int value_type )
{
ON_Value* value = 0;
switch((unsigned int)value_type)
{
case no_value_type:
break;
case bool_value:
value = new ON_BoolValue();
break;
case int_value:
value = new ON_IntValue();
break;
case double_value:
value = new ON_DoubleValue();
break;
case color_value:
value = new ON_ColorValue();
break;
case point_value:
value = new ON_PointValue();
break;
case vector_value:
value = new ON_VectorValue();
break;
case xform_value:
value = new ON_XformValue();
break;
case string_value:
value = new ON_StringValue();
break;
case objref_value:
value = new ON_ObjRefValue();
break;
case geometry_value:
value = new ON_GeometryValue();
break;
case uuid_value:
value = new ON_UuidValue();
break;
case point_on_object_value:
//value = new ON_PointOnObjectValue();
break;
case polyedge_value:
value = new ON_PolyEdgeHistoryValue();
break;
case subd_edge_chain_value:
value = new ON_SubDEdgeChainHistoryValue();
break;
case force_32bit_enum:
break;
default:
break;
}
return value;
}
///////////////////////////////////////////////////////////////////////
//
// ON_HistoryRecord implementation
//
ON_OBJECT_IMPLEMENT(ON_HistoryRecord,ON_ModelComponent,"ECD0FD2F-2088-49dc-9641-9CF7A28FFA6B");
ON_HistoryRecord::ON_HistoryRecord() ON_NOEXCEPT
: ON_ModelComponent(ON_ModelComponent::Type::HistoryRecord)
{}
ON_HistoryRecord::~ON_HistoryRecord()
{
Internal_Destroy();
}
ON_HistoryRecord::ON_HistoryRecord(const ON_HistoryRecord& src)
: ON_ModelComponent(ON_ModelComponent::Type::HistoryRecord,src)
{
Internal_Copy(src);
}
ON_HistoryRecord& ON_HistoryRecord::operator=(const ON_HistoryRecord& src)
{
if ( this != &src && false == this->IsSystemComponent() )
{
ON_ModelComponent::operator=(*this);
Internal_Destroy();
ON_Object::operator=(src);
Internal_Copy(src);
}
return *this;
}
void ON_HistoryRecord::Internal_Copy(const ON_HistoryRecord& src)
{
// input value of this->m_value[] is known to be empty
m_command_id = src.m_command_id;
m_version = src.m_version;
m_record_type = src.m_record_type;
m_descendants = src.m_descendants;
m_antecedents = src.m_antecedents;
m_bValuesSorted = true;
m_bCopyOnReplaceObject = src.m_bCopyOnReplaceObject;
const unsigned int count = src.m_value.UnsignedCount();
m_value.SetCapacity(count);
const ON_Value* prev_v = 0;
for (unsigned int i = 0; i < count; i++)
{
const ON_Value* src_v = src.m_value[i];
if (src_v)
{
ON_Value* v = src_v->Duplicate();
if (v)
{
m_value.Append(v);
if (m_bValuesSorted && prev_v && prev_v->m_value_id > v->m_value_id)
m_bValuesSorted = false;
prev_v = v;
}
}
}
}
bool ON_HistoryRecord::IsValid( ON_TextLog* text_log ) const
{
return true;
}
void ON_HistoryRecord::Internal_Destroy()
{
const unsigned int count = m_value.UnsignedCount();
for ( unsigned int i = 0; i < count; i++ )
{
ON_Value* v = m_value[i];
if (nullptr != v)
{
m_value[i] = nullptr;
delete v;
}
}
m_value.Empty();
}
ON_HistoryRecord::RECORD_TYPE ON_HistoryRecord::RecordType(int i)
{
switch (i)
{
case (int)ON_HistoryRecord::RECORD_TYPE::history_parameters:
return ON_HistoryRecord::RECORD_TYPE::history_parameters;
case (int)ON_HistoryRecord::RECORD_TYPE::feature_parameters:
return ON_HistoryRecord::RECORD_TYPE::feature_parameters;
}
return ON_HistoryRecord::RECORD_TYPE::history_parameters;
}
bool ON_HistoryRecord::SetBoolValue( int value_id, bool b)
{
return ( 1 == SetBoolValues(value_id, 1, &b) );
}
bool ON_HistoryRecord::SetIntValue( int value_id, int i)
{
return ( 1 == SetIntValues(value_id, 1, &i) );
}
bool ON_HistoryRecord::SetDoubleValue( int value_id, double x)
{
return ( 1 == SetDoubleValues(value_id, 1, &x) );
}
bool ON_HistoryRecord::SetPointValue( int value_id, ON_3dPoint p)
{
return ( 1 == SetPointValues(value_id, 1, &p) );
}
bool ON_HistoryRecord::SetVectorValue( int value_id, ON_3dVector v)
{
return ( 1 == SetVectorValues(value_id, 1, &v) );
}
bool ON_HistoryRecord::SetXformValue( int value_id, ON_Xform xform)
{
return ( 1 == SetXformValues(value_id, 1, &xform) );
}
bool ON_HistoryRecord::SetColorValue( int value_id, ON_Color c)
{
return ( 1 == SetColorValues(value_id, 1, &c) );
}
bool ON_HistoryRecord::SetObjRefValue( int value_id, const ON_ObjRef& oref)
{
return ( 1 == SetObjRefValues(value_id, 1, &oref) );
}
bool ON_HistoryRecord::SetPointOnObjectValue( int value_id, const ON_ObjRef& oref, ON_3dPoint point )
{
ON_ObjRef poo = oref;
poo.m_point = point;
return SetObjRefValue(value_id,poo);
}
bool ON_HistoryRecord::GetPointOnObjectValue( int value_id, ON_ObjRef& oref ) const
{
bool rc = GetObjRefValue(value_id,oref);
return (rc && oref.m_point.IsValid());
}
bool ON_HistoryRecord::SetGeometryValue( int value_id, ON_Geometry* g)
{
ON_SimpleArray<ON_Geometry*> a(1);
a.Append(g);
return SetGeometryValues(value_id, a);
}
bool ON_HistoryRecord::SetPolyEdgeValue( int value_id, const ON_PolyEdgeHistory& polyedge )
{
return ( 1 == SetPolyEdgeValues(value_id, 1, &polyedge) );
}
bool ON_HistoryRecord::SetUuidValue( int value_id, ON_UUID uuid )
{
return ( 1 == SetUuidValues(value_id, 1, &uuid) );
}
static
int CompareValueIdHelper(const ON_Value* a, const ON_Value* b )
{
if (!a)
{
return b ? -1 : 0;
}
if (!b)
{
return 1;
}
return (a->m_value_id - b->m_value_id);
}
static int CompareValueId( ON_Value * const * a, ON_Value * const * b )
{
// handle NULLs in case somebody messes up the m_value[] array.
if ( !a )
{
return b ? -1 : 0;
}
if (!b)
return 1;
return CompareValueIdHelper(*a,*b);
}
ON_Value* ON_HistoryRecord::FindValueHelper( int value_id, int value_type, bool bCreateOne ) const
{
ON_HistoryRecord* vp = const_cast<ON_HistoryRecord*>(this);
if ( m_value.Count() > 0 )
{
if ( !m_bValuesSorted )
{
vp->m_value.QuickSort(CompareValueId);
vp->m_bValuesSorted = true;
}
ON_DummyValue dummy_value;
dummy_value.m_value_id = value_id;
ON_Value* p = &dummy_value;
int i = m_value.BinarySearch(&p,CompareValueId);
if ( i >= 0 )
{
// m_value[i]->m_value_id == value_id
if ( value_type == ((int)m_value[i]->m_value_type) )
{
// type matches
return m_value[i];
}
if ( bCreateOne )
{
// type does not match - replace the existing one
ON_Value* new_value = ON_Value::CreateValue(value_type);
if ( new_value )
{
new_value->m_value_id = value_id;
delete m_value[i];
vp->m_value[i] = new_value;
return new_value;
}
}
}
else if ( bCreateOne )
{
// no value in m_value[] array with a matching value_id
ON_Value* new_value = ON_Value::CreateValue(value_type);
if ( new_value )
{
new_value->m_value_id = value_id;
if ( m_bValuesSorted && (*m_value.Last())->m_value_id > value_id )
vp->m_bValuesSorted = false;
vp->m_value.Append(new_value);
return new_value;
}
}
}
else if ( bCreateOne )
{
ON_Value* new_value = ON_Value::CreateValue(value_type);
if ( new_value )
{
new_value->m_value_id = value_id;
vp->m_bValuesSorted = true;
vp->m_value.Append(new_value);
return new_value;
}
}
return 0;
}
bool ON_HistoryRecord::SetBoolValues( int value_id, int count, const bool* b)
{
ON_BoolValue* v = static_cast<ON_BoolValue*>(FindValueHelper(value_id,ON_Value::bool_value,true));
if ( v )
{
v->m_value.SetCount(0);
v->m_value.SetCapacity(count);
v->m_value.Append(count,b);
}
return (0 != v);
}
bool ON_HistoryRecord::SetIntValues( int value_id, int count, const int* i)
{
ON_IntValue* v = static_cast<ON_IntValue*>(FindValueHelper(value_id,ON_Value::int_value,true));
if ( v )
{
v->m_value.SetCount(0);
v->m_value.SetCapacity(count);
v->m_value.Append(count,i);
}
return (0 != v);
}
bool ON_HistoryRecord::SetDoubleValues( int value_id, int count, const double* x)
{
ON_DoubleValue* v = static_cast<ON_DoubleValue*>(FindValueHelper(value_id,ON_Value::double_value,true));
if ( v )
{
v->m_value.SetCount(0);
v->m_value.SetCapacity(count);
v->m_value.Append(count,x);
}
return (0 != v);
}
bool ON_HistoryRecord::SetPointValues( int value_id, int count, const ON_3dPoint* P)
{
ON_PointValue* v = static_cast<ON_PointValue*>(FindValueHelper(value_id,ON_Value::point_value,true));
if ( v )
{
v->m_value.SetCount(0);
v->m_value.SetCapacity(count);
v->m_value.Append(count,P);
}
return (0 != v);
}
bool ON_HistoryRecord::SetVectorValues( int value_id, int count, const ON_3dVector* V)
{
ON_VectorValue* v = static_cast<ON_VectorValue*>(FindValueHelper(value_id,ON_Value::vector_value,true));
if ( v )
{
v->m_value.SetCount(0);
v->m_value.SetCapacity(count);
v->m_value.Append(count,V);
}
return (0 != v);
}
bool ON_HistoryRecord::SetXformValues( int value_id, int count, const ON_Xform* xform)
{
ON_XformValue* v = static_cast<ON_XformValue*>(FindValueHelper(value_id,ON_Value::xform_value,true));
if ( v )
{
v->m_value.SetCount(0);
v->m_value.SetCapacity(count);
v->m_value.Append(count,xform);
}
return (0 != v);
}
bool ON_HistoryRecord::SetColorValues( int value_id, int count, const ON_Color* c)
{
ON_ColorValue* v = static_cast<ON_ColorValue*>(FindValueHelper(value_id,ON_Value::color_value,true));
if ( v )
{
v->m_value.SetCount(0);
v->m_value.SetCapacity(count);
v->m_value.Append(count,c);
}
return (0 != v);
}
bool ON_HistoryRecord::SetUuidValues( int value_id, int count, const ON_UUID* u )
{
ON_UuidValue* v = static_cast<ON_UuidValue*>(FindValueHelper(value_id,ON_Value::uuid_value,true));
if ( v )
{
v->m_value.SetCount(0);
v->m_value.SetCapacity(count);
v->m_value.Append(count,u);
}
return (0 != v);
}
bool ON_HistoryRecord::SetStringValues( int value_id, int count, const wchar_t* const* s )
{
ON_StringValue* v = static_cast<ON_StringValue*>(FindValueHelper(value_id,ON_Value::string_value,true));
if ( v )
{
v->m_value.Destroy();
v->m_value.Reserve(count);
int i;
for( i = 0; i < count; i++ )
{
v->m_value.AppendNew() = s[i];
}
}
return (0 != v);
}
bool ON_HistoryRecord::SetStringValues( int value_id, const ON_ClassArray<ON_wString>& s )
{
ON_StringValue* v = static_cast<ON_StringValue*>(FindValueHelper(value_id,ON_Value::string_value,true));
if ( v )
{
v->m_value = s;
}
return (0 != v);
}
bool ON_HistoryRecord::SetStringValue( int value_id, const wchar_t* s )
{
ON_StringValue* v = static_cast<ON_StringValue*>(FindValueHelper(value_id,ON_Value::string_value,true));
if ( v )
{
v->m_value.Destroy();
v->m_value.AppendNew() = s;
}
return (0 != v);
}
bool ON_HistoryRecord::SetObjRefValues( int value_id, int count, const ON_ObjRef* oref)
{
ON_ObjRefValue* v = static_cast<ON_ObjRefValue*>(FindValueHelper(value_id,ON_Value::objref_value,true));
if ( v )
{
v->m_value.Destroy();
v->m_value.Reserve(count);
if(count)
{
// 2019-01-23 - kike@mcneel.com
// Objects in instance definitions can not be modified in that case
// I add the root instance reference and all the instance definitions as 'antecedents'
const bool idef_geometry = oref && (oref->m__iref.Count() > 0);
for(int i = 0; i < count; i++)
{
// The call to DecrementProxyReferenceCount() is critical.
// It makes sure there are no active runtime pointers
// saved in the history record. If this call is not here,
// you will eventually crash and history update will never
// work right even when it doesn't crash.
ON_ObjRef& vor = v->m_value.AppendNew();
vor = oref[i];
vor.DecrementProxyReferenceCount();
// Feb 12 2010 - Fixing bug in ExtrudeCrv history
// and probably lots of other subtle history bugs.
// History must lookup by UUID and not by runtime serial number.
vor.m_runtime_sn = 0;
// 2019-01-23 - kike@mcneel.com
if(!idef_geometry)
{
ON_UUID object_id = v->m_value[i].m_uuid;
if(!ON_UuidIsNil(object_id))
{
m_antecedents.AddUuid(object_id);
}
}
}
// 2019-01-23 - kike@mcneel.com
if(idef_geometry)
{
if(auto iref = oref->m__iref.Last())
m_antecedents.AddUuid(iref->m_iref_uuid);
for(int r = 0; r < oref->m__iref.Count(); ++r)
m_antecedents.AddUuid(oref->m__iref[r].m_idef_uuid);
}
}
}
return (0 != v);
}
bool ON_HistoryRecord::SetGeometryValues(int value_id, const ON_SimpleArray<ON_Geometry*> a)
{
ON_GeometryValue* v = static_cast<ON_GeometryValue*>(FindValueHelper(value_id, ON_Value::geometry_value, true));
if (v)
{
v->m_value = a;
}
return (0 != v);
}
bool ON_HistoryRecord::SetSubDEdgeChainValue(int value_id, const ON_SubDEdgeChain& edge_chain)
{
ON_SimpleArray<const ON_SubDEdgeChain*> a;
a.Append(&edge_chain);
return ON_HistoryRecord::SetSubDEdgeChainValues(value_id, a);
}
bool ON_HistoryRecord::SetSubDEdgeChainValues(int value_id, const ON_ClassArray<ON_SubDEdgeChain>& edge_chains)
{
const unsigned count = edge_chains.UnsignedCount();
ON_SimpleArray<const ON_SubDEdgeChain*> a(count);
for (unsigned i = 0; i < count; ++i)
a.Append(&edge_chains[i]);
return ON_HistoryRecord::SetSubDEdgeChainValues(value_id, a);
}
bool ON_HistoryRecord::SetSubDEdgeChainValues(int value_id, const ON_SimpleArray<const ON_SubDEdgeChain*>& edge_chains)
{
// validate
const unsigned count = edge_chains.UnsignedCount();
if (count <= 0)
return false;
for (unsigned i = 0; i < count; ++i)
{
const ON_SubDEdgeChain* c = edge_chains[i];
if (nullptr == c)
return false;
const ON_UUID parent_subd_id = c->PersistentSubDId();
if (ON_nil_uuid == parent_subd_id)
return false; // a persistent id is required so that update history can find the new subd and update the runtime ON_SubDEdgePtr values.
if (c->EdgeCount() <= 0)
return false;
if (false == c->HasPersistentEdgeIds())
{
c->SetPersistentEdgeIdsFromRuntimeEdgePtrs();
if (false == c->HasPersistentEdgeIds())
return false;
}
m_antecedents.AddUuid(parent_subd_id, true);
}
// copy edge chains and add
ON_SubDEdgeChainHistoryValue* v = static_cast<ON_SubDEdgeChainHistoryValue*>(FindValueHelper(value_id, ON_Value::subd_edge_chain_value, true));
if ( nullptr != v )
{
v->m_value.Reserve(count);
for (unsigned i = 0; i < count; ++i)
v->m_value.Append(new ON_SubDEdgeChain(*edge_chains[i]));
}
return (nullptr != v);
}
bool ON_HistoryRecord::SetPolyEdgeValues( int value_id, int count, const ON_PolyEdgeHistory* a )
{
ON_PolyEdgeHistoryValue* v = static_cast<ON_PolyEdgeHistoryValue*>(FindValueHelper(value_id,ON_Value::polyedge_value,true));
if ( v )
{
v->m_value.Destroy();
v->m_value.Append(count,a);
for ( int i = 0; i < count; i++ )
{
const ON_PolyEdgeHistory& pe_history = a[i];
for ( int j = 0; j < pe_history.m_segment.Count(); j++ )
{
const ON_CurveProxyHistory& segment = pe_history.m_segment[j];
m_antecedents.AddUuid(segment.m_curve_ref.m_uuid);
}
}
}
return (0 != v);
}
bool ON_HistoryRecord::GetBoolValue( int value_id, bool* b ) const
{
bool rc = false;
const ON_BoolValue* v = static_cast<ON_BoolValue*>(FindValueHelper(value_id,ON_Value::bool_value,0));
if ( v && 1 == v->m_value.Count())
{
*b = v->m_value[0];
rc = true;
}
return rc;
}
bool ON_HistoryRecord::GetIntValue( int value_id, int* i ) const
{
bool rc = false;
const ON_IntValue* v = static_cast<ON_IntValue*>(FindValueHelper(value_id,ON_Value::int_value,0));
if ( v && 1 == v->m_value.Count())
{
*i = v->m_value[0];
rc = true;
}
return rc;
}
bool ON_HistoryRecord::GetDoubleValue( int value_id, double* number ) const
{
bool rc = false;
const ON_DoubleValue* v = static_cast<ON_DoubleValue*>(FindValueHelper(value_id,ON_Value::double_value,0));
if ( v && 1 == v->m_value.Count())
{
*number = v->m_value[0];
rc = true;
}
return rc;
}
bool ON_HistoryRecord::GetPointValue( int value_id, ON_3dPoint& point ) const
{
bool rc = false;
const ON_PointValue* v = static_cast<ON_PointValue*>(FindValueHelper(value_id,ON_Value::point_value,0));
if ( v && 1 == v->m_value.Count())
{
point = v->m_value[0];
rc = true;
}
return rc;
}
bool ON_HistoryRecord::GetVectorValue( int value_id, ON_3dVector& vector ) const
{
bool rc = false;
const ON_VectorValue* v = static_cast<ON_VectorValue*>(FindValueHelper(value_id,ON_Value::vector_value,0));
if ( v && 1 == v->m_value.Count())
{
vector = v->m_value[0];
rc = true;
}
return rc;
}
bool ON_HistoryRecord::GetXformValue( int value_id, ON_Xform& xform ) const
{
bool rc = false;
const ON_XformValue* v = static_cast<ON_XformValue*>(FindValueHelper(value_id,ON_Value::xform_value,0));
if ( v && 1 == v->m_value.Count())
{
xform = v->m_value[0];
rc = true;
}
return rc;
}
bool ON_HistoryRecord::GetColorValue( int value_id, ON_Color* color ) const
{
bool rc = false;
const ON_ColorValue* v = static_cast<ON_ColorValue*>(FindValueHelper(value_id,ON_Value::color_value,0));
if ( v && 1 == v->m_value.Count())
{
*color = v->m_value[0];
rc = true;
}
return rc;
}
bool ON_HistoryRecord::GetObjRefValue( int value_id, ON_ObjRef& oref ) const
{
bool rc = false;
const ON_ObjRefValue* v = static_cast<ON_ObjRefValue*>(FindValueHelper(value_id,ON_Value::objref_value,0));
if ( v && 1 == v->m_value.Count())
{
oref = v->m_value[0];
rc = true;
}
return rc;
}
bool ON_HistoryRecord::GetStringValue( int value_id, ON_wString& str ) const
{
bool rc = false;
ON_StringValue* v = static_cast<ON_StringValue*>(FindValueHelper(value_id,ON_Value::string_value,0));
if ( v && 1 == v->m_value.Count())
{
str = v->m_value[0];
rc = true;
}
return rc;
}
bool ON_HistoryRecord::GetGeometryValue( int value_id, const ON_Geometry*& g ) const
{
bool rc = false;
g = 0;
const ON_GeometryValue* v = static_cast<ON_GeometryValue*>(FindValueHelper(value_id,ON_Value::geometry_value,0));
if ( v && 1 == v->m_value.Count())
{
g = v->m_value[0];
rc = true;
}
return rc;
}
bool ON_HistoryRecord::GetSubDEdgeChainValue(int value_id, const ON_SubDEdgeChain*& edge_chain) const
{
bool rc = false;
edge_chain = 0;
const ON_SubDEdgeChainHistoryValue* v = static_cast<ON_SubDEdgeChainHistoryValue*>(FindValueHelper(value_id, ON_Value::subd_edge_chain_value, 0));
if (v && 1 == v->m_value.Count())
{
edge_chain = v->m_value[0];
rc = true;
}
return rc;
}
bool ON_HistoryRecord::GetPolyEdgeValue( int value_id, const ON_PolyEdgeHistory*& polyedge ) const
{
bool rc = false;
polyedge = 0;
const ON_PolyEdgeHistoryValue* v = static_cast<ON_PolyEdgeHistoryValue*>(FindValueHelper(value_id,ON_Value::polyedge_value,0));
if ( v && 1 == v->m_value.Count())
{
polyedge = &v->m_value[0];
rc = true;
}
return rc;
}
bool ON_HistoryRecord::GetCurveValue( int value_id, const ON_Curve*& c ) const
{
c = 0;
const ON_Geometry* g = 0;
if (GetGeometryValue( value_id, g ))
{
c = ON_Curve::Cast(g);
}
return (0 != c);
}
bool ON_HistoryRecord::GetSurfaceValue( int value_id, const ON_Surface*& s ) const
{
s = 0;
const ON_Geometry* g = 0;
if (GetGeometryValue( value_id, g ))
{
s = ON_Surface::Cast(g);
}
return (0 != s);
}
bool ON_HistoryRecord::GetBrepValue( int value_id, const ON_Brep*& b ) const
{
b = 0;
const ON_Geometry* g = 0;
if (GetGeometryValue( value_id, g ))
{
b = ON_Brep::Cast(g);
}
return (0 != b);
}
bool ON_HistoryRecord::GetMeshValue( int value_id, const ON_Mesh*& m ) const
{
m = 0;
const ON_Geometry* g = 0;
if (GetGeometryValue( value_id, g ))
{
m = ON_Mesh::Cast(g);
}
return (0 != m);
}
bool ON_HistoryRecord::GetUuidValue( int value_id, ON_UUID* uuid ) const
{
bool rc = false;
const ON_UuidValue* v = static_cast<ON_UuidValue*>(FindValueHelper(value_id,ON_Value::uuid_value,0));
if ( v && 1 == v->m_value.Count())
{
*uuid = v->m_value[0];
rc = true;
}
return rc;
}
int ON_HistoryRecord::GetBoolValues( int value_id, ON_SimpleArray<bool>& a ) const
{
a.SetCount(0);
const ON_BoolValue* v = static_cast<ON_BoolValue*>(FindValueHelper(value_id,ON_Value::bool_value,0));
if ( v )
{
a = v->m_value;
}
return a.Count();
}
int ON_HistoryRecord::GetStringValues( int value_id, ON_ClassArray<ON_wString>& a ) const
{
a.SetCount(0);
const ON_StringValue* v = static_cast<ON_StringValue*>(FindValueHelper(value_id,ON_Value::string_value,0));
if ( v )
{
a = v->m_value;
}
return a.Count();
}
int ON_HistoryRecord::GetIntValues( int value_id, ON_SimpleArray<int>& a ) const
{
a.SetCount(0);
const ON_IntValue* v = static_cast<ON_IntValue*>(FindValueHelper(value_id,ON_Value::int_value,0));
if ( v )
{
a = v->m_value;
}
return a.Count();
}
int ON_HistoryRecord::GetDoubleValues( int value_id, ON_SimpleArray<double>& a) const
{
a.SetCount(0);
const ON_DoubleValue* v = static_cast<ON_DoubleValue*>(FindValueHelper(value_id,ON_Value::double_value,0));
if ( v )
{
a = v->m_value;
}
return a.Count();
}
int ON_HistoryRecord::GetPointValues( int value_id, ON_SimpleArray<ON_3dPoint>& a ) const
{
a.SetCount(0);
const ON_PointValue* v = static_cast<ON_PointValue*>(FindValueHelper(value_id,ON_Value::point_value,0));
if ( v )
{
a = v->m_value;
}
return a.Count();
}
int ON_HistoryRecord::GetVectorValues( int value_id, ON_SimpleArray<ON_3dVector>& a ) const
{
a.SetCount(0);
const ON_VectorValue* v = static_cast<ON_VectorValue*>(FindValueHelper(value_id,ON_Value::vector_value,0));
if ( v )
{
a = v->m_value;
}
return a.Count();
}
int ON_HistoryRecord::GetXformValues( int value_id, ON_SimpleArray<ON_Xform>& a ) const
{
a.SetCount(0);
const ON_XformValue* v = static_cast<ON_XformValue*>(FindValueHelper(value_id,ON_Value::xform_value,0));
if ( v )
{
a = v->m_value;
}
return a.Count();
}
int ON_HistoryRecord::GetColorValues( int value_id, ON_SimpleArray<ON_Color>& a ) const
{
a.SetCount(0);
const ON_ColorValue* v = static_cast<ON_ColorValue*>(FindValueHelper(value_id,ON_Value::color_value,0));
if ( v )
{
a = v->m_value;
}
return a.Count();
}
int ON_HistoryRecord::GetObjRefValues( int value_id, ON_ClassArray<ON_ObjRef>& a ) const
{
a.SetCount(0);
const ON_ObjRefValue* v = static_cast<ON_ObjRefValue*>(FindValueHelper(value_id,ON_Value::objref_value,0));
if ( v )
{
a = v->m_value;
}
return a.Count();
}
int ON_HistoryRecord::GetGeometryValues( int value_id, ON_SimpleArray<const ON_Geometry*>& a) const
{
a.SetCount(0);
const ON_GeometryValue* v = static_cast<ON_GeometryValue*>(FindValueHelper(value_id,ON_Value::geometry_value,0));
if ( v )
{
int i, count = v->m_value.Count();
a.Reserve(count);
for ( i = 0; i < count; i++ )
a.Append(v->m_value[i]);
}
return a.Count();
}
int ON_HistoryRecord::GetSubDEdgeChainValues(int value_id, ON_SimpleArray<const ON_SubDEdgeChain*>& a) const
{
a.SetCount(0);
const ON_SubDEdgeChainHistoryValue* v = static_cast<ON_SubDEdgeChainHistoryValue*>(FindValueHelper(value_id, ON_Value::subd_edge_chain_value, 0));
if (v)
{
int i, count = v->m_value.Count();
a.Reserve(count);
for (i = 0; i < count; i++)
a.Append(v->m_value[i]);
}
return a.Count();
}
int ON_HistoryRecord::GetPolyEdgeValues( int value_id, ON_SimpleArray<const ON_PolyEdgeHistory*>& a) const
{
a.SetCount(0);
const ON_PolyEdgeHistoryValue* v = static_cast<ON_PolyEdgeHistoryValue*>(FindValueHelper(value_id,ON_Value::polyedge_value,0));
if ( v )
{
int i, count = v->m_value.Count();
a.Reserve(count);
for ( i = 0; i < count; i++ )
a.Append(&v->m_value[i]);
}
return a.Count();
}
int ON_HistoryRecord::GetUuidValues( int value_id, ON_SimpleArray<ON_UUID>& a) const
{
a.SetCount(0);
const ON_UuidValue* v = static_cast<ON_UuidValue*>(FindValueHelper(value_id,ON_Value::uuid_value,0));
if ( v )
{
a = v->m_value;
}
return a.Count();
}
bool ON_HistoryRecord::IsAntecedent( ON_UUID object_uuid ) const
{
return m_antecedents.FindUuid(object_uuid);
}
int ON_HistoryRecord::ValueReport( ON_TextLog& text_log ) const
{
int value_count = 0;
int i, vi, count = m_value.Count();
// list values
ON_SimpleArray<int> vi_list(count);
vi_list.SetCount(count);
vi_list.Zero();
m_value.Sort( ON::sort_algorithm::quick_sort, vi_list.Array(), CompareValueId );
for ( i = 0; i < count; i++ )
{
vi = vi_list[i];
const ON_Value* v = m_value[vi];
if (!v)
continue;
text_log.Print("Value ID %d:\n",v->m_value_id);
text_log.PushIndent();
m_value[i]->ReportHelper(text_log);
text_log.PopIndent();
value_count++;
}
return value_count;
}
void ON_HistoryRecord::Dump( ON_TextLog& text_log ) const
{
ON_ModelComponent::Dump(text_log);
int i, count;
ON_SimpleArray<ON_UUID> uuid_list;
text_log.Print("Command ID: ");
text_log.Print(m_command_id);
text_log.Print("\n");
text_log.Print("Version %d\n",m_version);
text_log.Print("Record ID: ");
text_log.Print(Id());
text_log.Print("\n");
text_log.Print("Record type: %s\n",
(m_record_type == ON_HistoryRecord::RECORD_TYPE::feature_parameters)
? "feature parameters" : "history parameters");
// list antecedents
uuid_list.SetCount(0);
m_antecedents.GetUuids(uuid_list);
count = uuid_list.Count();
if ( count <= 0 )
{
text_log.Print("No antededents.\n");
}
else
{
text_log.Print("Antededent ID:\n");
text_log.PushIndent();
for ( i = 0; i < count; i++ )
{
text_log.Print(uuid_list[i]);
text_log.Print("\n");
}
text_log.PopIndent();
}
// list descendants
uuid_list.SetCount(0);
m_descendants.GetUuids(uuid_list);
count = uuid_list.Count();
if ( count <= 0 )
{
text_log.Print("No descendants.\n");
}
else
{
text_log.Print("Descendant ID:\n");
text_log.PushIndent();
for ( i = 0; i < count; i++ )
{
text_log.Print(uuid_list[i]);
text_log.Print("\n");
}
text_log.PopIndent();
}
text_log.Print("Values:\n");
text_log.PushIndent();
int value_count = ValueReport(text_log);
if ( 0 == value_count )
text_log.Print("none\n");
text_log.PopIndent();
}
void ON_HistoryRecord::DestroyValue( int value_id )
{
if ( m_value.Count() > 0 )
{
if ( !m_bValuesSorted )
{
m_value.QuickSort(CompareValueId);
m_bValuesSorted = true;
}
ON_DummyValue dummy_value;
dummy_value.m_value_id = value_id;
ON_Value* p = &dummy_value;
int i = m_value.BinarySearch(&p,CompareValueId);
if ( i >= 0 )
{
ON_Value* v = m_value[i];
m_value.Remove();
delete v;
}
}
}
bool ON_HistoryRecord::Read(ON_BinaryArchive& archive)
{
return Internal_ReadV5(archive);
}
bool ON_HistoryRecord::Internal_ReadV5( ON_BinaryArchive& archive )
{
*this = ON_HistoryRecord::Empty;
// put entire history record in a chunk
int major_version = 0;
int minor_version = 0;
bool rc = archive.BeginRead3dmChunk(TCODE_ANONYMOUS_CHUNK,&major_version,&minor_version);
if (!rc)
return false;
for(;;)
{
rc = (1 == major_version);
if (!rc) break;
ON_UUID record_id = ON_nil_uuid;
rc = archive.ReadUuid(record_id);
if(!rc) break;
SetId(record_id);
rc = archive.ReadInt(&m_version);
if(!rc) break;
rc = archive.ReadUuid(m_command_id);
if(!rc) break;
// 16 October 2012 Dale Lear
// Fixing http://dev.mcneel.com/bugtrack/?q=101403
// Changing bSortDescendantsAfterRead from true to false
// per discussion in the bug report.
const bool bSortDescendantsAferRead = false;
rc = m_descendants.Read(archive,bSortDescendantsAferRead);
if(!rc) break;
rc = m_antecedents.Read(archive);
if(!rc) break;
// all values are in a chunk
int mjvs=0,mnvs=0;
int value_id0 = 0;
rc = archive.BeginRead3dmChunk(TCODE_ANONYMOUS_CHUNK,&mjvs,&mnvs);
if (rc)
{
rc = ( 1 == mjvs );
int i, count = 0;
if (rc)
rc = archive.ReadInt(&count);
if (rc)
m_value.Reserve(count);
for ( i = 0; i < count && rc; i++ )
{
int mjv=0,mnv=0;
rc = archive.BeginRead3dmChunk(TCODE_ANONYMOUS_CHUNK,&mjv,&mnv);
if ( !rc)
break;
for(;;)
{
rc = ( 1 == mjv);
if (!rc) break;
int value_type = ON_Value::no_value_type;
rc = archive.ReadInt(&value_type);
if (!rc)
break;
int value_id = 0;
rc = archive.ReadInt(&value_id);
if (!rc)
break;
ON_Value* value = ON_Value::CreateValue(value_type);
if ( value )
{
value->m_value_id = value_id;
rc = value->ReadHelper(archive);
if (!rc)
{
delete value;
break;
}
m_value.Append(value);
if ( value->m_value_id <= value_id0 )
m_bValuesSorted = false;
else
value_id0 = value->m_value_id;
}
break;
}
if (!archive.EndRead3dmChunk())
rc = false;
}
// end of all values
if (!archive.EndRead3dmChunk())
rc = false;
}
if ( rc && minor_version >= 1 )
{
// 1.1 fields added to opennurbs version 200603200
int rec_type = (int)ON_HistoryRecord::RECORD_TYPE::history_parameters;
if (rc)
rc = archive.ReadInt( &rec_type );
if (rc )
m_record_type = RecordType(rec_type);
if (rc && minor_version >= 2)
{
archive.ReadBool(&m_bCopyOnReplaceObject);
}
}
break;
}
// end of entire history record in a chunk
if (!archive.EndRead3dmChunk())
rc = false;
return rc;
}
bool ON_HistoryRecord::Write(ON_BinaryArchive& archive) const
{
return Internal_WriteV5(archive);
}
bool ON_HistoryRecord::Internal_WriteV5( ON_BinaryArchive& archive ) const
{
// 2015-06-01 Dale Lear
// Save m_bCopyOnReplaceObject in the file in chunk version 1.2
const int minor_version
= (archive.Archive3dmVersion() >= 60)
? 2 // V6 after 2015-06-01 or later file
: 1; // V5 or earlier file
bool rc = archive.BeginWrite3dmChunk(TCODE_ANONYMOUS_CHUNK,1,minor_version);
if (!rc)
return false;
for(;;)
{
rc = archive.WriteUuid(Id());
if(!rc) break;
rc = archive.WriteInt(m_version);
if(!rc) break;
rc = archive.WriteUuid(m_command_id);
if(!rc) break;
// 30 October 2012 Dale Lear
// Fixing http://dev.mcneel.com/bugtrack/?q=101403
// Changing bSortDescendantsBeforeWrite from true to false
// per discussion in the bug report.
const bool bSortDescendantsBeforeWrite = false;
rc = m_descendants.Write(archive,bSortDescendantsBeforeWrite);
if(!rc) break;
rc = m_antecedents.Write(archive);
if(!rc) break;
// wrap all values in a chunk
rc = archive.BeginWrite3dmChunk(TCODE_ANONYMOUS_CHUNK,1,0);
if (rc)
{
// value count
int i, count = m_value.Count();
rc = archive.WriteInt(count);
for ( i = 0; i < count && rc; i++ )
{
// put individual value in its own chunk
rc = archive.BeginWrite3dmChunk(TCODE_ANONYMOUS_CHUNK,1,0);
if ( !rc)
break;
for(;;)
{
const ON_Value* value = m_value[i];
rc = archive.WriteInt(value ? value->m_value_type : ON_Value::no_value_type );
if (!rc) break;
rc = archive.WriteInt(value ? value->m_value_id : 0 );
if (!rc) break;
if ( value && value->m_value_type != ON_Value::no_value_type )
rc = value->WriteHelper(archive);
if (!rc) break;
break;
}
// end of individual value chunk
if (!archive.EndWrite3dmChunk())
rc = false;
}
// end of all values chunk
if ( !archive.EndWrite3dmChunk() )
rc = false;
}
// 1.1 fields added to opennurbs version 200603200
if (rc)
{
int i = (int)m_record_type;
rc = archive.WriteInt(i);
}
if (rc && minor_version >= 2)
{
rc = archive.WriteBool(m_bCopyOnReplaceObject);
}
break;
}
if (!archive.EndWrite3dmChunk())
rc = false;
return rc;
}
void ON_HistoryRecord::RemapObjectIds( const ON_SimpleArray<ON_UuidPair>& id_remap )
{
if ( id_remap.Count() > 0 )
{
int i, j;
m_antecedents.RemapUuids(id_remap);
m_descendants.RemapUuids(id_remap);
for ( i = 0; i < m_value.Count(); i++ )
{
ON_Value* v = m_value[i];
if ( v && ON_Value::objref_value == v->m_value_type )
{
ON_ObjRefValue* objrev_v = static_cast<ON_ObjRefValue*>(v);
for ( j = 0; j < objrev_v->m_value.Count(); j++ )
{
objrev_v->m_value[j].RemapObjectId(id_remap);
}
}
// 24 May 2021, Mikko, RH-56171:
// Some commands like Offset use an UUID list to map inputs and outputs.
// Similar to remapping the objref ids, the uuid lists also need to be
// updated to use new ids.
// Other commands that currently use UUID lists are Divide, Slab, Ribbon,
// FilletSrf, ChamferSrf, ArrayCrv, Hatch.
else if (v && ON_Value::uuid_value == v->m_value_type)
{
ON_UuidValue* uuid_v = static_cast<ON_UuidValue*>(v);
for (j = 0; j < uuid_v->m_value.Count(); j++)
{
int index = id_remap.BinarySearch((const ON_UuidPair*)&uuid_v->m_value[j], ON_UuidPair::CompareFirstUuid);
if (index >= 0)
uuid_v->m_value[j] = id_remap[index].m_uuid[1];
}
}
// 27 Oct 2021, Mikko, RH-66102:
// Polyedge values contain objrefs and also need remapping.
// This fixes history replay not working properly on BlendSrf and others
// when importing/pasting.
else if (v && ON_Value::polyedge_value == v->m_value_type)
{
ON_PolyEdgeHistoryValue* objrev_v = static_cast<ON_PolyEdgeHistoryValue*>(v);
for (j = 0; j < objrev_v->m_value.Count(); j++)
{
int k;
for (k = 0; k < objrev_v->m_value[j].m_segment.Count(); k++)
{
objrev_v->m_value[j].m_segment[k].m_curve_ref.RemapObjectId(id_remap);
}
}
}
}
}
}
bool ON_HistoryRecord::CopyOnReplaceObject() const
{
return m_bCopyOnReplaceObject;
}
void ON_HistoryRecord::SetCopyOnReplaceObject(
bool bCopyOnReplaceObject
)
{
m_bCopyOnReplaceObject = (bCopyOnReplaceObject) ? true : false;
}
/////////////////////////////////////////////////////////////////////////////////
//
// ON_CurveProxyHistory
//
ON_CurveProxyHistory::ON_CurveProxyHistory()
{
}
ON_CurveProxyHistory::~ON_CurveProxyHistory()
{
}
void ON_CurveProxyHistory::Destroy()
{
m_curve_ref.Destroy();
m_bReversed = false;
m_full_real_curve_domain = ON_Interval::EmptyInterval;
m_sub_real_curve_domain = ON_Interval::EmptyInterval;
m_proxy_curve_domain = ON_Interval::EmptyInterval;
m_segment_edge_domain = ON_Interval::EmptyInterval;
m_segment_trim_domain = ON_Interval::EmptyInterval;
}
bool ON_CurveProxyHistory::Write( ON_BinaryArchive& file ) const
{
if ( !file.BeginWrite3dmChunk( TCODE_ANONYMOUS_CHUNK,1,1) )
return false;
bool rc = false;
for(;;)
{
if ( !m_curve_ref.Write(file) )
break;
if ( !file.WriteBool(m_bReversed) )
break;
if ( !file.WriteInterval(m_full_real_curve_domain) )
break;
if ( !file.WriteInterval(m_sub_real_curve_domain) )
break;
if (!file.WriteInterval(m_proxy_curve_domain))
break;
// Added in version 1,1
if (!file.WriteInterval(m_segment_edge_domain))
break;
if (!file.WriteInterval(m_segment_trim_domain))
break;
rc = true;
break;
}
if ( !file.EndWrite3dmChunk() )
rc = false;
return rc;
}
bool ON_CurveProxyHistory::Read( ON_BinaryArchive& file )
{
int version_major = 0;
int version_minor = 0;
Destroy();
if ( !file.BeginRead3dmChunk( TCODE_ANONYMOUS_CHUNK,&version_major,&version_minor) )
return false;
bool rc = false;
for(;;)
{
if ( 1 != version_major )
break;
if ( !m_curve_ref.Read(file) )
break;
if ( !file.ReadBool(&m_bReversed) )
break;
if ( !file.ReadInterval(m_full_real_curve_domain) )
break;
if ( !file.ReadInterval(m_sub_real_curve_domain) )
break;
if (!file.ReadInterval(m_proxy_curve_domain))
break;
if (version_minor > 0)
{
if (!file.ReadInterval(m_segment_edge_domain))
break;
if (!file.ReadInterval(m_segment_trim_domain))
break;
}
rc = true;
break;
}
if ( !file.EndRead3dmChunk() )
rc = false;
return rc;
}
void ON_CurveProxyHistory::Dump( ON_TextLog& ) const
{
}
/////////////////////////////////////////////////////////////////////////////////
//
// ON_PolyEdgeHistory
//
ON_PolyEdgeHistory::ON_PolyEdgeHistory()
: m_evaluation_mode(0)
{
}
ON_PolyEdgeHistory::~ON_PolyEdgeHistory()
{
}
void ON_PolyEdgeHistory::Destroy()
{
m_segment.Destroy();
m_t.Destroy();
m_evaluation_mode = 0;
}
bool ON_PolyEdgeHistory::Write( ON_BinaryArchive& file ) const
{
int i;
if ( !file.BeginWrite3dmChunk( TCODE_ANONYMOUS_CHUNK,1,0) )
return false;
bool rc = false;
for(;;)
{
if ( !file.WriteInt(m_segment.Count()) )
break;
for ( i = 0; i < m_segment.Count(); i++ )
{
if ( !m_segment[i].Write(file) )
break;
}
if ( i < m_segment.Count() )
break;
if ( !file.WriteInt(m_t.Count()) )
break;
if ( m_t.Count() > 0 )
{
if ( !file.WriteDouble(m_t.Count(),m_t.Array()) )
break;
}
if ( !file.WriteInt(m_evaluation_mode) )
break;
rc = true;
break;
}
if ( !file.EndWrite3dmChunk() )
rc = false;
return rc;
}
bool ON_PolyEdgeHistory::Read( ON_BinaryArchive& file )
{
int count, i;
int version_major = 0;
int version_minor = 0;
Destroy();
if ( !file.BeginRead3dmChunk( TCODE_ANONYMOUS_CHUNK,&version_major,&version_minor) )
return false;
bool rc = false;
for(;;)
{
if ( 1 != version_major )
break;
count = 0;
if ( !file.ReadInt(&count) )
break;
m_segment.Reserve(count);
for ( i = 0; i < count; i++ )
{
if ( !m_segment.AppendNew().Read(file) )
break;
}
if ( i < count )
break;
count = 0;
if ( !file.ReadInt(&count) )
break;
if ( count > 0 )
{
m_t.Reserve(count);
m_t.SetCount(count);
if ( !file.ReadDouble(count,m_t.Array()) )
break;
}
if ( !file.ReadInt(&m_evaluation_mode) )
break;
rc = true;
break;
}
if ( !file.EndRead3dmChunk() )
rc = false;
return rc;
}
void ON_PolyEdgeHistory::Dump( ON_TextLog& ) const
{
}