Files
test2/source/blender/freestyle/intern/geometry/GeomCleaner.cpp

Ignoring revisions in .git-blame-ignore-revs. Click here to bypass and see the normal blame view.

244 lines
6.8 KiB
C++
Raw Normal View History

/* SPDX-FileCopyrightText: 2012-2022 Blender Authors
*
* SPDX-License-Identifier: GPL-2.0-or-later */
/** \file
* \ingroup freestyle
* \brief Class to define a cleaner of geometry providing a set of useful tools
*/
#if 0
# if defined(__GNUC__) && (__GNUC__ >= 3)
// hash_map is not part of the C++ standard anymore;
// hash_map.h has been kept though for backward compatibility
2019-01-03 15:52:07 +11:00
# include <hash_map.h>
# else
2019-01-03 15:52:07 +11:00
# include <hash_map>
# endif
#endif
2008-04-30 15:41:54 +00:00
#include <cstdio>
2008-04-30 15:41:54 +00:00
#include <list>
#include <map>
2008-04-30 15:41:54 +00:00
#include "GeomCleaner.h"
#include "../system/TimeUtils.h"
#include "BKE_global.hh"
#include "BLI_sys_types.h"
2008-04-30 15:41:54 +00:00
using namespace std;
Attempt to fix a potential name conflict between Freestyle and the compositor. A crash in the Freestyle renderer was reported by Ton on IRC with a stack trace below. Note that #2 is in Freestyle, whereas #1 is in the compositor. The problem was observed in a debug build on OS X 10.7 (gcc 4.2, openmp disabled, no llvm). ---------------------------------------------------------------------- Program received signal EXC_BAD_ACCESS, Could not access memory. Reason: 13 at address: 0x0000000000000000 [Switching to process 72386 thread 0xf303] 0x0000000100c129f3 in NodeBase::~NodeBase (this=0x10e501c80) at COM_NodeBase.cpp:43 43 delete (this->m_outputsockets.back()); Current language: auto; currently c++ (gdb) where #0 0x0000000100c129f3 in NodeBase::~NodeBase (this=0x10e501c80) at COM_NodeBase.cpp:43 #1 0x0000000100c29066 in Node::~Node (this=0x10e501c80) at COM_Node.h:49 #2 0x000000010089c273 in NodeShape::~NodeShape (this=0x10e501c80) at NodeShape.cpp:43 #3 0x000000010089910b in NodeGroup::destroy (this=0x10e501da0) at NodeGroup.cpp:61 #4 0x00000001008990cd in NodeGroup::destroy (this=0x10e5014b0) at NodeGroup.cpp:59 #5 0x00000001008990cd in NodeGroup::destroy (this=0x114e18da0) at NodeGroup.cpp:59 #6 0x00000001007e6602 in Controller::ClearRootNode (this=0x114e19640) at Controller.cpp:329 #7 0x00000001007ea52e in Controller::LoadMesh (this=0x114e19640, re=0x10aba4638, srl=0x1140f5258) at Controller.cpp:302 #8 0x00000001008030ad in prepare (re=0x10aba4638, srl=0x1140f5258) at FRS_freestyle.cpp:302 #9 0x000000010080457a in FRS_do_stroke_rendering (re=0x10aba4638, srl=0x1140f5258) at FRS_freestyle.cpp:600 #10 0x00000001006aeb9d in add_freestyle (re=0x10aba4638) at pipeline.c:1584 #11 0x00000001006aceb7 in do_render_3d (re=0x10aba4638) at pipeline.c:1094 #12 0x00000001006ae061 in do_render_fields_blur_3d (re=0x10aba4638) at pipeline.c:1367 #13 0x00000001006afa16 in do_render_composite_fields_blur_3d (re=0x10aba4638) at pipeline.c:1815 #14 0x00000001006b04e4 in do_render_all_options (re=0x10aba4638) at pipeline.c:2021 ---------------------------------------------------------------------- Apparently a name conflict between the two Blender modules is taking place. The present commit hence intends to address it by putting all the Freestyle C++ classes in the namespace 'Freestyle'. This revision will also prevent potential name conflicts with other Blender modules in the future. Special thanks to Lukas Toenne for the help with C++ namespace.
2013-04-09 00:46:49 +00:00
namespace Freestyle {
2008-04-30 15:41:54 +00:00
void GeomCleaner::SortIndexedVertexArray(const float *iVertices,
uint iVSize,
const uint *iIndices,
uint iISize,
float **oVertices,
uint **oIndices)
2008-04-30 15:41:54 +00:00
{
// First, we build a list of IndexVertex:
list<IndexedVertex> indexedVertices;
uint i;
for (i = 0; i < iVSize; i += 3) {
indexedVertices.emplace_back(Vec3f(iVertices[i], iVertices[i + 1], iVertices[i + 2]), i / 3);
}
// q-sort
indexedVertices.sort();
// build the indices mapping array:
uint *mapIndices = new uint[iVSize / 3];
*oVertices = new float[iVSize];
list<IndexedVertex>::iterator iv;
uint newIndex = 0;
uint vIndex = 0;
for (iv = indexedVertices.begin(); iv != indexedVertices.end(); iv++) {
// Build the final results:
(*oVertices)[vIndex] = iv->x();
(*oVertices)[vIndex + 1] = iv->y();
(*oVertices)[vIndex + 2] = iv->z();
mapIndices[iv->index()] = newIndex;
newIndex++;
vIndex += 3;
}
// Build the final index array:
*oIndices = new uint[iISize];
for (i = 0; i < iISize; i++) {
(*oIndices)[i] = 3 * mapIndices[iIndices[i] / 3];
}
delete[] mapIndices;
2008-04-30 15:41:54 +00:00
}
void GeomCleaner::CompressIndexedVertexArray(const float *iVertices,
uint iVSize,
const uint *iIndices,
uint iISize,
float **oVertices,
uint *oVSize,
uint **oIndices)
2008-04-30 15:41:54 +00:00
{
// First, we build a list of IndexVertex:
vector<Vec3f> vertices;
uint i;
for (i = 0; i < iVSize; i += 3) {
vertices.emplace_back(iVertices[i], iVertices[i + 1], iVertices[i + 2]);
}
uint *mapVertex = new uint[iVSize];
vector<Vec3f>::iterator v = vertices.begin();
vector<Vec3f> compressedVertices;
Vec3f previous = *v;
mapVertex[0] = 0;
compressedVertices.push_back(vertices.front());
v++;
Vec3f current;
i = 1;
for (; v != vertices.end(); v++) {
current = *v;
if (current == previous) {
mapVertex[i] = compressedVertices.size() - 1;
}
else {
compressedVertices.push_back(current);
mapVertex[i] = compressedVertices.size() - 1;
}
previous = current;
i++;
}
// Builds the resulting vertex array:
*oVSize = 3 * compressedVertices.size();
*oVertices = new float[*oVSize];
i = 0;
for (v = compressedVertices.begin(); v != compressedVertices.end(); v++) {
(*oVertices)[i] = (*v)[0];
(*oVertices)[i + 1] = (*v)[1];
(*oVertices)[i + 2] = (*v)[2];
i += 3;
}
// Map the index array:
*oIndices = new uint[iISize];
for (i = 0; i < iISize; i++) {
(*oIndices)[i] = 3 * mapVertex[iIndices[i] / 3];
}
delete[] mapVertex;
2008-04-30 15:41:54 +00:00
}
void GeomCleaner::SortAndCompressIndexedVertexArray(const float *iVertices,
uint iVSize,
const uint *iIndices,
uint iISize,
float **oVertices,
uint *oVSize,
uint **oIndices)
2008-04-30 15:41:54 +00:00
{
// tmp arrays used to store the sorted data:
float *tmpVertices;
uint *tmpIndices;
Chronometer chrono;
// Sort data
chrono.start();
GeomCleaner::SortIndexedVertexArray(
iVertices, iVSize, iIndices, iISize, &tmpVertices, &tmpIndices);
if (G.debug & G_DEBUG_FREESTYLE) {
printf("Sorting: %lf sec.\n", chrono.stop());
}
// compress data
chrono.start();
GeomCleaner::CompressIndexedVertexArray(
tmpVertices, iVSize, tmpIndices, iISize, oVertices, oVSize, oIndices);
real duration = chrono.stop();
if (G.debug & G_DEBUG_FREESTYLE) {
printf("Merging: %lf sec.\n", duration);
}
// deallocates memory:
delete[] tmpVertices;
delete[] tmpIndices;
2008-04-30 15:41:54 +00:00
}
/** Defines a hash table used for searching the Cells */
struct GeomCleanerHasher {
2008-04-30 15:41:54 +00:00
#define _MUL 950706376UL
#define _MOD 2147483647UL
inline size_t operator()(const Vec3r &p) const
{
size_t res = ulong(p[0] * _MUL) % _MOD;
res = (res + ulong(p[1]) * _MUL) % _MOD;
return (res + ulong(p[2]) * _MUL) % _MOD;
}
#undef _MUL
#undef _MOD
2008-04-30 15:41:54 +00:00
};
void GeomCleaner::CleanIndexedVertexArray(const float *iVertices,
uint iVSize,
const uint *iIndices,
uint iISize,
float **oVertices,
uint *oVSize,
uint **oIndices)
2008-04-30 15:41:54 +00:00
{
using cleanHashTable = map<Vec3f, uint>;
vector<Vec3f> vertices;
uint i;
for (i = 0; i < iVSize; i += 3) {
vertices.emplace_back(iVertices[i], iVertices[i + 1], iVertices[i + 2]);
}
cleanHashTable ht;
vector<uint> newIndices;
vector<Vec3f> newVertices;
// elimination of needless points
uint currentIndex = 0;
vector<Vec3f>::const_iterator v = vertices.begin();
vector<Vec3f>::const_iterator end = vertices.end();
cleanHashTable::const_iterator found;
for (; v != end; v++) {
found = ht.find(*v);
if (found != ht.end()) {
// The vertex is already in the new array.
newIndices.push_back((*found).second);
}
else {
newVertices.push_back(*v);
newIndices.push_back(currentIndex);
ht[*v] = currentIndex;
currentIndex++;
}
}
// creation of oVertices array:
*oVSize = 3 * newVertices.size();
*oVertices = new float[*oVSize];
currentIndex = 0;
end = newVertices.end();
for (v = newVertices.begin(); v != end; v++) {
(*oVertices)[currentIndex++] = (*v)[0];
(*oVertices)[currentIndex++] = (*v)[1];
(*oVertices)[currentIndex++] = (*v)[2];
}
// map new indices:
*oIndices = new uint[iISize];
for (i = 0; i < iISize; i++) {
(*oIndices)[i] = 3 * newIndices[iIndices[i] / 3];
}
2008-04-30 15:41:54 +00:00
}
Attempt to fix a potential name conflict between Freestyle and the compositor. A crash in the Freestyle renderer was reported by Ton on IRC with a stack trace below. Note that #2 is in Freestyle, whereas #1 is in the compositor. The problem was observed in a debug build on OS X 10.7 (gcc 4.2, openmp disabled, no llvm). ---------------------------------------------------------------------- Program received signal EXC_BAD_ACCESS, Could not access memory. Reason: 13 at address: 0x0000000000000000 [Switching to process 72386 thread 0xf303] 0x0000000100c129f3 in NodeBase::~NodeBase (this=0x10e501c80) at COM_NodeBase.cpp:43 43 delete (this->m_outputsockets.back()); Current language: auto; currently c++ (gdb) where #0 0x0000000100c129f3 in NodeBase::~NodeBase (this=0x10e501c80) at COM_NodeBase.cpp:43 #1 0x0000000100c29066 in Node::~Node (this=0x10e501c80) at COM_Node.h:49 #2 0x000000010089c273 in NodeShape::~NodeShape (this=0x10e501c80) at NodeShape.cpp:43 #3 0x000000010089910b in NodeGroup::destroy (this=0x10e501da0) at NodeGroup.cpp:61 #4 0x00000001008990cd in NodeGroup::destroy (this=0x10e5014b0) at NodeGroup.cpp:59 #5 0x00000001008990cd in NodeGroup::destroy (this=0x114e18da0) at NodeGroup.cpp:59 #6 0x00000001007e6602 in Controller::ClearRootNode (this=0x114e19640) at Controller.cpp:329 #7 0x00000001007ea52e in Controller::LoadMesh (this=0x114e19640, re=0x10aba4638, srl=0x1140f5258) at Controller.cpp:302 #8 0x00000001008030ad in prepare (re=0x10aba4638, srl=0x1140f5258) at FRS_freestyle.cpp:302 #9 0x000000010080457a in FRS_do_stroke_rendering (re=0x10aba4638, srl=0x1140f5258) at FRS_freestyle.cpp:600 #10 0x00000001006aeb9d in add_freestyle (re=0x10aba4638) at pipeline.c:1584 #11 0x00000001006aceb7 in do_render_3d (re=0x10aba4638) at pipeline.c:1094 #12 0x00000001006ae061 in do_render_fields_blur_3d (re=0x10aba4638) at pipeline.c:1367 #13 0x00000001006afa16 in do_render_composite_fields_blur_3d (re=0x10aba4638) at pipeline.c:1815 #14 0x00000001006b04e4 in do_render_all_options (re=0x10aba4638) at pipeline.c:2021 ---------------------------------------------------------------------- Apparently a name conflict between the two Blender modules is taking place. The present commit hence intends to address it by putting all the Freestyle C++ classes in the namespace 'Freestyle'. This revision will also prevent potential name conflicts with other Blender modules in the future. Special thanks to Lukas Toenne for the help with C++ namespace.
2013-04-09 00:46:49 +00:00
} /* namespace Freestyle */