mirror of
https://github.com/mcneel/opennurbs.git
synced 2026-03-20 09:29:26 +08:00
Sync changes from upstream repository
This commit is contained in:
@@ -26,7 +26,7 @@
|
||||
|
||||
static ON_4dPoint UNSET_4D_POINT = ON_4dPoint(ON_UNSET_VALUE, ON_UNSET_VALUE, ON_UNSET_VALUE, ON_UNSET_VALUE);
|
||||
|
||||
ON__UINT32 ON_DecalCRCFromNode(const ON_XMLNode& node)
|
||||
ON_DECAL_CRC ON_DecalCRCFromNode(const ON_XMLNode& node)
|
||||
{
|
||||
return ON_Decal::ComputeDecalCRC(0, node);
|
||||
}
|
||||
@@ -34,8 +34,9 @@ ON__UINT32 ON_DecalCRCFromNode(const ON_XMLNode& node)
|
||||
class ON_Decal::CImpl : public ON_InternalXMLImpl
|
||||
{
|
||||
public:
|
||||
CImpl() { ON_CreateUuid(_decal_id); }
|
||||
CImpl(ON_DecalCollection& dc, ON_XMLNode& node) : _collection(&dc), ON_InternalXMLImpl(&node) { ON_CreateUuid(_decal_id); }
|
||||
CImpl();
|
||||
CImpl(ON_DecalCollection* dc, ON_XMLNode& node);
|
||||
CImpl(ON_DecalCollection* dc, const ON_XMLNode& node);
|
||||
|
||||
ON_UUID TextureInstanceId(void) const;
|
||||
void SetTextureInstanceId(const ON_UUID& id);
|
||||
@@ -110,6 +111,27 @@ static ON_Decal::Mappings MappingFromString(const ON_wString& s)
|
||||
return ON_Decal::Mappings::None;
|
||||
}
|
||||
|
||||
ON_Decal::CImpl::CImpl()
|
||||
{
|
||||
ON_CreateUuid(_decal_id);
|
||||
}
|
||||
|
||||
ON_Decal::CImpl::CImpl(ON_DecalCollection* dc, ON_XMLNode& node)
|
||||
:
|
||||
_collection(dc),
|
||||
ON_InternalXMLImpl(&node)
|
||||
{
|
||||
ON_CreateUuid(_decal_id);
|
||||
}
|
||||
|
||||
ON_Decal::CImpl::CImpl(ON_DecalCollection* dc, const ON_XMLNode& node)
|
||||
:
|
||||
_collection(dc),
|
||||
ON_InternalXMLImpl(&const_cast<ON_XMLNode&>(node))
|
||||
{
|
||||
ON_CreateUuid(_decal_id);
|
||||
}
|
||||
|
||||
ON_XMLVariant ON_Decal::CImpl::GetParameter(const wchar_t* param_name, const ON_XMLVariant& def) const
|
||||
{
|
||||
return ON_InternalXMLImpl::GetParameter(L"", param_name, def);
|
||||
@@ -462,11 +484,25 @@ ON_Decal::ON_Decal()
|
||||
_impl = new CImpl;
|
||||
}
|
||||
|
||||
ON_Decal::ON_Decal(ON_XMLNode& node)
|
||||
{
|
||||
ON_ASSERT(node.TagName() == ON_RDK_DECAL);
|
||||
|
||||
_impl = new CImpl(nullptr, node);
|
||||
}
|
||||
|
||||
ON_Decal::ON_Decal(const ON_XMLNode& node)
|
||||
{
|
||||
ON_ASSERT(node.TagName() == ON_RDK_DECAL);
|
||||
|
||||
_impl = new CImpl(nullptr, node);
|
||||
}
|
||||
|
||||
ON_Decal::ON_Decal(ON_DecalCollection& dc, ON_XMLNode& node)
|
||||
{
|
||||
ON_ASSERT(node.TagName() == ON_RDK_DECAL);
|
||||
|
||||
_impl = new CImpl(dc, node);
|
||||
_impl = new CImpl(&dc, node);
|
||||
}
|
||||
|
||||
ON_Decal::ON_Decal(const ON_Decal& d)
|
||||
@@ -679,9 +715,9 @@ ON_UUID ON_Decal::Id(void) const
|
||||
return _impl->Id();
|
||||
}
|
||||
|
||||
ON__UINT32 ON_Decal::DecalCRC(void) const
|
||||
ON_DECAL_CRC ON_Decal::DecalCRC(void) const
|
||||
{
|
||||
return DataCRC(0);
|
||||
return ComputeDecalCRC(0, _impl->Node());
|
||||
}
|
||||
|
||||
ON__UINT32 ON_Decal::DataCRC(ON__UINT32 current_remainder) const
|
||||
@@ -734,6 +770,21 @@ bool ON_Decal::SetCustomXML(const ON_UUID& renderEngineId, const ON_XMLNode& cus
|
||||
return true;
|
||||
}
|
||||
|
||||
void ON_Decal::AppendCustomXML(const ON_XMLNode& custom_node)
|
||||
{
|
||||
// This function only exists to support the RDK.
|
||||
|
||||
ON_ASSERT(custom_node.TagName() == L"entire-custom-xml");
|
||||
|
||||
ON_XMLNode* child = custom_node.FirstChild();
|
||||
while (nullptr != child)
|
||||
{
|
||||
_impl->Node().AttachChildNode(new ON_XMLNode(*child));
|
||||
|
||||
child = custom_node.NextSibling();
|
||||
}
|
||||
}
|
||||
|
||||
// Copied from IRhRdkDecal::GetTextureMapping -- TODO: Refactor. [JOHN-DECAL-FIX]
|
||||
bool ON_Decal::GetTextureMapping(ON_TextureMapping& mappingOut) const
|
||||
{
|
||||
@@ -810,24 +861,24 @@ bool ON_Decal::GetTextureMapping(ON_TextureMapping& mappingOut) const
|
||||
This object encapsulates the reading of all decal properties from XML nodes.
|
||||
It is used by the decal CRC calculation in ComputeDecalCRC().
|
||||
|
||||
TODO: It could also be used by the ON_Decal XML node access.
|
||||
TODO: It could also be used by the ON_Decal XML node access (for Rhino 9).
|
||||
|
||||
*/
|
||||
class ON_DecalNodeReader
|
||||
{
|
||||
public:
|
||||
ON_DecalNodeReader(const ON_XMLNode* p) : m_pNode(p) { }
|
||||
ON_DecalNodeReader(const ON_XMLNode* decal_node);
|
||||
|
||||
ON_XMLVariant Mapping(void) const { return Value(ON_RDK_DECAL_MAPPING, ON_RDK_DECAL_MAPPING_NONE); }
|
||||
ON_XMLVariant Projection(void) const { return Value(ON_RDK_DECAL_PROJECTION, ON_RDK_DECAL_PROJECTION_NONE); }
|
||||
ON_XMLVariant MapToInside(void) const { return Value(ON_RDK_DECAL_MAP_TO_INSIDE_ON, m_def.MapToInside()); }
|
||||
ON_XMLVariant Transparency(void) const { return Value(ON_RDK_DECAL_TRANSPARENCY , m_def.Transparency()); }
|
||||
ON_XMLVariant TextureInstanceId(void) const { return Value(ON_RDK_DECAL_TEXTURE_INSTANCE, m_def.TextureInstanceId()); }
|
||||
ON_XMLVariant Height(void) const { return Value(ON_RDK_DECAL_HEIGHT , m_def.Height()); }
|
||||
ON_XMLVariant Radius(void) const { return Value(ON_RDK_DECAL_RADIUS , m_def.Radius()); }
|
||||
ON_XMLVariant Origin(void) const { return Value(ON_RDK_DECAL_ORIGIN , m_def.Origin()); }
|
||||
ON_XMLVariant VectorUp(void) const { return Value(ON_RDK_DECAL_VECTOR_UP , ON_3dPoint(m_def.VectorUp())); }
|
||||
ON_XMLVariant VectorAcross(void) const { return Value(ON_RDK_DECAL_VECTOR_ACROSS , ON_3dPoint(m_def.VectorAcross())); }
|
||||
ON_XMLVariant MapToInside(void) const { return Value(ON_RDK_DECAL_MAP_TO_INSIDE_ON, _def.MapToInside()); }
|
||||
ON_XMLVariant Transparency(void) const { return Value(ON_RDK_DECAL_TRANSPARENCY , _def.Transparency()); }
|
||||
ON_XMLVariant TextureInstanceId(void) const { return Value(ON_RDK_DECAL_TEXTURE_INSTANCE, _def.TextureInstanceId()); }
|
||||
ON_XMLVariant Height(void) const { return Value(ON_RDK_DECAL_HEIGHT , _def.Height()); }
|
||||
ON_XMLVariant Radius(void) const { return Value(ON_RDK_DECAL_RADIUS , _def.Radius()); }
|
||||
ON_XMLVariant Origin(void) const { return Value(ON_RDK_DECAL_ORIGIN , _def.Origin()); }
|
||||
ON_XMLVariant VectorUp(void) const { return Value(ON_RDK_DECAL_VECTOR_UP , ON_3dPoint(_def.VectorUp())); }
|
||||
ON_XMLVariant VectorAcross(void) const { return Value(ON_RDK_DECAL_VECTOR_ACROSS , ON_3dPoint(_def.VectorAcross())); }
|
||||
ON_XMLVariant HorzSweepSta(void) const { return Value(ON_RDK_DECAL_HORZ_SWEEP_STA , DefaultHorzSweepSta()); }
|
||||
ON_XMLVariant HorzSweepEnd(void) const { return Value(ON_RDK_DECAL_HORZ_SWEEP_END , DefaultHorzSweepEnd()); }
|
||||
ON_XMLVariant VertSweepSta(void) const { return Value(ON_RDK_DECAL_VERT_SWEEP_STA , DefaultVertSweepSta()); }
|
||||
@@ -837,109 +888,79 @@ public:
|
||||
ON_XMLVariant MaxU(void) const { return Value(ON_RDK_DECAL_MAX_U , DefaultMaxU()); }
|
||||
ON_XMLVariant MaxV(void) const { return Value(ON_RDK_DECAL_MAX_V , DefaultMaxV()); }
|
||||
ON_XMLVariant IsTemporary(void) const { return Value(ON_RDK_DECAL_IS_TEMPORARY , false); }
|
||||
ON_XMLVariant IsVisible(void) const { return Value(ON_RDK_DECAL_IS_VISIBLE , m_def.IsVisible()); }
|
||||
ON_XMLVariant InstanceId(void) const { return Value(ON_RDK_DECAL_INSTANCE_ID , m_def.Id()); }
|
||||
ON_XMLVariant IsVisible(void) const { return Value(ON_RDK_DECAL_IS_VISIBLE , _def.IsVisible()); }
|
||||
ON_XMLVariant InstanceId(void) const { return Value(ON_RDK_DECAL_INSTANCE_ID , _def.Id()); }
|
||||
|
||||
private:
|
||||
ON_XMLVariant Value(const wchar_t* wszName, const ON_XMLVariant& vDefault) const;
|
||||
|
||||
double DefaultHorzSweepSta(void) const { double a, b; m_def.GetHorzSweep(a, b); return a; }
|
||||
double DefaultHorzSweepEnd(void) const { double a, b; m_def.GetHorzSweep(a, b); return b; }
|
||||
double DefaultVertSweepSta(void) const { double a, b; m_def.GetVertSweep(a, b); return a; }
|
||||
double DefaultVertSweepEnd(void) const { double a, b; m_def.GetVertSweep(a, b); return b; }
|
||||
double DefaultHorzSweepSta(void) const { double a, b; _def.GetHorzSweep(a, b); return a; }
|
||||
double DefaultHorzSweepEnd(void) const { double a, b; _def.GetHorzSweep(a, b); return b; }
|
||||
double DefaultVertSweepSta(void) const { double a, b; _def.GetVertSweep(a, b); return a; }
|
||||
double DefaultVertSweepEnd(void) const { double a, b; _def.GetVertSweep(a, b); return b; }
|
||||
|
||||
double DefaultMinU(void) const { double a, b, c, d; m_def.GetUVBounds(a, b, c, d); return a; }
|
||||
double DefaultMinV(void) const { double a, b, c, d; m_def.GetUVBounds(a, b, c, d); return b; }
|
||||
double DefaultMaxU(void) const { double a, b, c, d; m_def.GetUVBounds(a, b, c, d); return c; }
|
||||
double DefaultMaxV(void) const { double a, b, c, d; m_def.GetUVBounds(a, b, c, d); return d; }
|
||||
double DefaultMinU(void) const { double a, b, c, d; _def.GetUVBounds(a, b, c, d); return a; }
|
||||
double DefaultMinV(void) const { double a, b, c, d; _def.GetUVBounds(a, b, c, d); return b; }
|
||||
double DefaultMaxU(void) const { double a, b, c, d; _def.GetUVBounds(a, b, c, d); return c; }
|
||||
double DefaultMaxV(void) const { double a, b, c, d; _def.GetUVBounds(a, b, c, d); return d; }
|
||||
|
||||
private:
|
||||
const ON_XMLNode* m_pNode;
|
||||
const ON_Decal m_def;
|
||||
const ON_XMLNode* _decal_node;
|
||||
const ON_Decal _def;
|
||||
};
|
||||
|
||||
ON_DecalNodeReader::ON_DecalNodeReader(const ON_XMLNode* decal_node)
|
||||
:
|
||||
_decal_node(decal_node)
|
||||
{
|
||||
ON_ASSERT(_decal_node && (_decal_node->TagName() == ON_RDK_DECAL));
|
||||
}
|
||||
|
||||
ON_XMLVariant ON_DecalNodeReader::Value(const wchar_t* wszName, const ON_XMLVariant& vDefault) const
|
||||
{
|
||||
ON_XMLVariant vValue = vDefault;
|
||||
|
||||
if (nullptr != m_pNode)
|
||||
if (nullptr != _decal_node)
|
||||
{
|
||||
const ON_XMLParameters p(*m_pNode);
|
||||
const ON_XMLParameters p(*_decal_node);
|
||||
p.GetParam(wszName, vValue);
|
||||
}
|
||||
|
||||
return vValue;
|
||||
}
|
||||
|
||||
static void DecalUpdateCRC(ON__UINT32& crc, const ON_XMLVariant value)
|
||||
#if (defined _DEBUG) && (defined HUMAN_READABLE_DECAL_CRC)
|
||||
#define ON_DECAL_PROP_NAME(s) , s
|
||||
static void DecalUpdateCRC(ON_DECAL_CRC& crc, const ON_XMLVariant value, const wchar_t* name)
|
||||
{
|
||||
crc = value.DataCRC(crc);
|
||||
crc._info1 += ON_wString(name) + L"=" + value.AsString() + ON_wString(L" ");
|
||||
crc._info2 += ON_wString(name) + L"=" + value.AsString() + ON_wString(L"\n");
|
||||
}
|
||||
#else
|
||||
#define ON_DECAL_PROP_NAME(s)
|
||||
static void DecalUpdateCRC(ON_DECAL_CRC& crc, const ON_XMLVariant& value)
|
||||
{
|
||||
crc = value.DataCRC(crc);
|
||||
}
|
||||
#endif
|
||||
|
||||
ON__UINT32 ON_Decal::ComputeDecalCRC(ON__UINT32 crc, const ON_XMLNode& node) // Static.
|
||||
static void DecalUpdateCRC_Custom(const ON_XMLNode& decal_node, ON_DECAL_CRC& crc)
|
||||
{
|
||||
const ON_DecalNodeReader d(&node);
|
||||
|
||||
const ON_wString s = d.Mapping().AsString();
|
||||
const auto mapping = MappingFromString(s);
|
||||
|
||||
DecalUpdateCRC(crc, d.Mapping());
|
||||
DecalUpdateCRC(crc, d.IsVisible());
|
||||
DecalUpdateCRC(crc, d.IsTemporary());
|
||||
DecalUpdateCRC(crc, d.Transparency());
|
||||
DecalUpdateCRC(crc, d.TextureInstanceId());
|
||||
|
||||
if (Mappings::Planar == mapping)
|
||||
{
|
||||
DecalUpdateCRC(crc, d.MinU());
|
||||
DecalUpdateCRC(crc, d.MinV());
|
||||
DecalUpdateCRC(crc, d.MaxU());
|
||||
DecalUpdateCRC(crc, d.MaxV());
|
||||
}
|
||||
else
|
||||
{
|
||||
DecalUpdateCRC(crc, d.Origin());
|
||||
DecalUpdateCRC(crc, d.VectorUp());
|
||||
DecalUpdateCRC(crc, d.VectorAcross());
|
||||
DecalUpdateCRC(crc, d.Projection());
|
||||
|
||||
if ((Mappings::Cylindrical == mapping) || (Mappings::Spherical == mapping))
|
||||
{
|
||||
DecalUpdateCRC(crc, d.Radius());
|
||||
DecalUpdateCRC(crc, d.MapToInside());
|
||||
DecalUpdateCRC(crc, d.HorzSweepSta());
|
||||
DecalUpdateCRC(crc, d.HorzSweepEnd());
|
||||
|
||||
if (Mappings::Cylindrical == mapping)
|
||||
{
|
||||
DecalUpdateCRC(crc, d.Height());
|
||||
}
|
||||
else
|
||||
if (Mappings::Spherical == mapping)
|
||||
{
|
||||
DecalUpdateCRC(crc, d.VertSweepSta());
|
||||
DecalUpdateCRC(crc, d.VertSweepEnd());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Look for custom data nodes and for each one, find the parameter node and then iterate over its
|
||||
// children and CRC the properties. For now, we will have to rely on the raw XML. A better solution
|
||||
// would be to have the plug-in that created this XML calculate the CRC itself.
|
||||
auto it = node.GetChildIterator();
|
||||
|
||||
const ON_wString custom = L"[CUSTOM] ";
|
||||
|
||||
auto it = decal_node.GetChildIterator();
|
||||
ON_XMLNode* pChildNode = nullptr;
|
||||
while (nullptr != (pChildNode = it.GetNextChild()))
|
||||
{
|
||||
if (pChildNode->TagName() != ON_RDK_DECAL_CUSTOM)
|
||||
continue; // Not a custom data node.
|
||||
|
||||
ON_XMLProperty* prop = pChildNode->GetNamedProperty(ON_RDK_DECAL_CUSTOM_RENDERER);
|
||||
if (nullptr != prop)
|
||||
{
|
||||
// Include the render engine id.
|
||||
const ON_UUID uuid = prop->GetValue().AsUuid();
|
||||
crc = ON_CRC32(crc, sizeof(uuid), &uuid);
|
||||
}
|
||||
const ON__UINT32 crc_before_custom_params = crc;
|
||||
|
||||
// Find the custom parameter node.
|
||||
const ON_XMLNode* pParamNode = pChildNode->GetNamedChild(ON_RDK_DECAL_CUSTOM_PARAMS);
|
||||
@@ -947,22 +968,103 @@ ON__UINT32 ON_Decal::ComputeDecalCRC(ON__UINT32 crc, const ON_XMLNode& node) //
|
||||
{
|
||||
// Iterate over the nodes inside the custom parameter node.
|
||||
const ON_XMLParameters p(*pParamNode);
|
||||
auto* pIterator = p.NewIterator();
|
||||
|
||||
ON_wString sParamName;
|
||||
ON_XMLVariant vParamValue;
|
||||
while (pIterator->Next(sParamName, vParamValue))
|
||||
auto* iterator = p.NewIterator();
|
||||
if (nullptr != iterator)
|
||||
{
|
||||
DecalUpdateCRC(crc, vParamValue);
|
||||
ON_wString sParamName;
|
||||
ON_XMLVariant vParamValue;
|
||||
while (iterator->Next(sParamName, vParamValue))
|
||||
{
|
||||
DecalUpdateCRC(crc, vParamValue ON_DECAL_PROP_NAME(custom + sParamName));
|
||||
}
|
||||
|
||||
delete iterator;
|
||||
}
|
||||
|
||||
delete pIterator;
|
||||
if (crc != crc_before_custom_params)
|
||||
{
|
||||
// 20th January 2025 John Croudy, https://mcneel.myjetbrains.com/youtrack/issue/RH-71351
|
||||
// Since the crc has changed, there must be some custom params, so only now do we include the render
|
||||
// engine id. Prior to this, the render engine id was getting included even when there were no custom
|
||||
// params. This caused the UI to overlook decals which were programatically created by clients.
|
||||
const ON_XMLProperty* prop = pChildNode->GetNamedProperty(ON_RDK_DECAL_CUSTOM_RENDERER);
|
||||
if (nullptr != prop)
|
||||
{
|
||||
// Include the render engine id.
|
||||
const ON_UUID uuid = prop->GetValue().AsUuid();
|
||||
DecalUpdateCRC(crc, uuid ON_DECAL_PROP_NAME(custom + L"render_engine_id"));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Make sure it's not zero which would mean 'nil'.
|
||||
if (0 == crc)
|
||||
crc--;
|
||||
ON_DECAL_CRC ON_Decal::ComputeDecalCRC(ON__UINT32 current_remainder, const ON_XMLNode& decal_node) // Static.
|
||||
{
|
||||
// The CRC of a decal is a unique value based on its state. It's created by CRC-ing all the decal properties
|
||||
// that affect the decal's appearance. We do not include the 'IsTemporary' property in the CRC because whether
|
||||
// or not a decal is temporary has nothing to do with what it looks like. We do however, include the 'IsVisible'
|
||||
// property because a decal being visible or invisible actually affects its appearance. Also, the RDK change
|
||||
// queue relies on the CRC to update the viewport so including the visibility is critical. Furthermore, the
|
||||
// CRC only includes the properties that are relevant for the decal's mapping type.
|
||||
|
||||
ON_DECAL_CRC crc = current_remainder;
|
||||
|
||||
if (decal_node.TagName() == ON_RDK_DECAL)
|
||||
{
|
||||
const ON_DecalNodeReader d(&decal_node);
|
||||
|
||||
DecalUpdateCRC(crc, d.Mapping() ON_DECAL_PROP_NAME(L"mapping"));
|
||||
DecalUpdateCRC(crc, d.IsVisible() ON_DECAL_PROP_NAME(L"visible"));
|
||||
DecalUpdateCRC(crc, d.Transparency() ON_DECAL_PROP_NAME(L"transparency"));
|
||||
DecalUpdateCRC(crc, d.TextureInstanceId() ON_DECAL_PROP_NAME(L"texture_id"));
|
||||
|
||||
const ON_Decal::Mappings mapping = MappingFromString(d.Mapping().AsString());
|
||||
|
||||
if (Mappings::UV == mapping)
|
||||
{
|
||||
DecalUpdateCRC(crc, d.MinU() ON_DECAL_PROP_NAME(L"min_u"));
|
||||
DecalUpdateCRC(crc, d.MinV() ON_DECAL_PROP_NAME(L"min_v"));
|
||||
DecalUpdateCRC(crc, d.MaxU() ON_DECAL_PROP_NAME(L"max_u"));
|
||||
DecalUpdateCRC(crc, d.MaxV() ON_DECAL_PROP_NAME(L"max_v"));
|
||||
}
|
||||
else
|
||||
{
|
||||
DecalUpdateCRC(crc, d.Origin() ON_DECAL_PROP_NAME(L"origin"));
|
||||
DecalUpdateCRC(crc, d.VectorUp() ON_DECAL_PROP_NAME(L"up"));
|
||||
DecalUpdateCRC(crc, d.VectorAcross() ON_DECAL_PROP_NAME(L"across"));
|
||||
|
||||
if ((Mappings::Cylindrical == mapping) || (Mappings::Spherical == mapping))
|
||||
{
|
||||
DecalUpdateCRC(crc, d.MapToInside() ON_DECAL_PROP_NAME(L"map_to_inside"));
|
||||
DecalUpdateCRC(crc, d.Radius() ON_DECAL_PROP_NAME(L"radius"));
|
||||
DecalUpdateCRC(crc, d.HorzSweepSta() ON_DECAL_PROP_NAME(L"horz_sweep_sta"));
|
||||
DecalUpdateCRC(crc, d.HorzSweepEnd() ON_DECAL_PROP_NAME(L"horz_sweep_end"));
|
||||
|
||||
if (Mappings::Cylindrical == mapping)
|
||||
{
|
||||
DecalUpdateCRC(crc, d.Height() ON_DECAL_PROP_NAME(L"height"));
|
||||
}
|
||||
else
|
||||
if (Mappings::Spherical == mapping)
|
||||
{
|
||||
DecalUpdateCRC(crc, d.VertSweepSta() ON_DECAL_PROP_NAME(L"vert_sweep_sta"));
|
||||
DecalUpdateCRC(crc, d.VertSweepEnd() ON_DECAL_PROP_NAME(L"vert_sweep_end"));
|
||||
}
|
||||
}
|
||||
else
|
||||
if (Mappings::Planar == mapping)
|
||||
{
|
||||
DecalUpdateCRC(crc, d.Projection() ON_DECAL_PROP_NAME(L"projection"));
|
||||
}
|
||||
}
|
||||
|
||||
DecalUpdateCRC_Custom(decal_node, crc);
|
||||
|
||||
// Make sure it's not nil.
|
||||
if (crc == ON_NIL_DECAL_CRC)
|
||||
crc = 0xFFFFFFFF;
|
||||
}
|
||||
|
||||
return crc;
|
||||
}
|
||||
@@ -1095,8 +1197,21 @@ const ON_DecalCollection& ON_DecalCollection::operator = (const ON_DecalCollecti
|
||||
|
||||
const ON_SimpleArray<ON_Decal*>& ON_DecalCollection::GetDecalArray(void) const
|
||||
{
|
||||
if (!m_populated)
|
||||
// 19th February 2025 John Croudy, https://mcneel.myjetbrains.com/youtrack/issue/RH-86089
|
||||
// The m_populated flag is an optimization designed to make sure we only populate the array when something
|
||||
// changes. Unfortunately, in Rhino 8, I forgot to add code to detect when a decal changes externally to this
|
||||
// class, and the array (which is essentially a cache) becomes invalid. This is fixed in Rhino 9 but the fix
|
||||
// is too complicated to backport to Rhino 8, so to get around this I'm just going to remove the optimization.
|
||||
|
||||
//if (!m_populated) // Always repopulate the array.
|
||||
{
|
||||
for (int i = 0; i < m_decals.Count(); i++)
|
||||
{
|
||||
delete m_decals[i];
|
||||
}
|
||||
|
||||
m_decals.Destroy();
|
||||
|
||||
Populate();
|
||||
|
||||
m_populated = true;
|
||||
|
||||
Reference in New Issue
Block a user