remove LOD_Decimator (c++ decimator), now replaced by bmesh decimator. also remove CTR c++ classes that are no longer used.

This commit is contained in:
Campbell Barton 2012-10-22 02:39:26 +00:00
parent 91ceb8f552
commit 226a5ee834
48 changed files with 13 additions and 5976 deletions

View File

@ -188,7 +188,6 @@ unset(PLATFORM_DEFAULT)
# Modifiers
option(WITH_MOD_FLUID "Enable Elbeem Modifier (Fluid Simulation)" ON)
option(WITH_MOD_SMOKE "Enable Smoke Modifier (Smoke Simulation)" ON)
option(WITH_MOD_DECIMATE "Enable Decimate Modifier" ON)
option(WITH_MOD_BOOLEAN "Enable Boolean Modifier" ON)
option(WITH_MOD_REMESH "Enable Remesh Modifier" ON)
option(WITH_MOD_CLOTH_ELTOPO "Enable Experimental cloth solver" OFF)
@ -2126,7 +2125,6 @@ if(FIRST_RUN)
info_cfg_text("Modifiers:")
info_cfg_option(WITH_MOD_BOOLEAN)
info_cfg_option(WITH_MOD_REMESH)
info_cfg_option(WITH_MOD_DECIMATE)
info_cfg_option(WITH_MOD_FLUID)
info_cfg_option(WITH_MOD_OCEANSIM)

View File

@ -264,7 +264,6 @@ if 'blenderlite' in B.targets:
target_env_defs['WITH_BF_FLUID'] = False
target_env_defs['WITH_BF_OCEANSIM'] = False
target_env_defs['WITH_BF_SMOKE'] = False
target_env_defs['WITH_BF_DECIMATE'] = False
target_env_defs['WITH_BF_BOOLEAN'] = False
target_env_defs['WITH_BF_REMESH'] = False
target_env_defs['WITH_BF_PYTHON'] = False

View File

@ -2,11 +2,9 @@ import os
IGNORE = (
"/test/",
"/decimate_glut_test/",
"/BSP_GhostTest/",
"/release/",
"/xembed/",
"/decimation/intern/future/",
"/TerraplayNetwork/",
"/ik_glut_test/",

View File

@ -35,7 +35,6 @@ set(WITH_JACK OFF CACHE FORCE BOOL)
set(WITH_LZMA OFF CACHE FORCE BOOL)
set(WITH_LZO OFF CACHE FORCE BOOL)
set(WITH_MOD_BOOLEAN OFF CACHE FORCE BOOL)
set(WITH_MOD_DECIMATE OFF CACHE FORCE BOOL)
set(WITH_MOD_FLUID OFF CACHE FORCE BOOL)
set(WITH_MOD_REMESH OFF CACHE FORCE BOOL)
set(WITH_MOD_SMOKE OFF CACHE FORCE BOOL)

View File

@ -152,7 +152,6 @@ def validate_arguments(args, bc):
'WITH_BF_RAYOPTIMIZATION',
'BF_RAYOPTIMIZATION_SSE_FLAGS',
'WITH_BF_FLUID',
'WITH_BF_DECIMATE',
'WITH_BF_BOOLEAN',
'WITH_BF_REMESH',
'WITH_BF_OCEANSIM',
@ -265,7 +264,6 @@ def read_opts(env, cfg, args):
('BF_PYTHON_ABI_FLAGS', 'Python ABI flags (suffix in library version: m, mu, etc)', ''),
(BoolVariable('WITH_BF_FLUID', 'Build with Fluid simulation (Elbeem)', True)),
(BoolVariable('WITH_BF_DECIMATE', 'Build with decimate modifier', True)),
(BoolVariable('WITH_BF_BOOLEAN', 'Build with boolean modifier', True)),
(BoolVariable('WITH_BF_REMESH', 'Build with remesh modifier', True)),
(BoolVariable('WITH_BF_OCEANSIM', 'Build with ocean simulation', False)),

View File

@ -49,11 +49,6 @@ if(WITH_MOD_SMOKE)
add_subdirectory(smoke)
endif()
if(WITH_MOD_DECIMATE)
add_subdirectory(container)
add_subdirectory(decimation)
endif()
if(WITH_MOD_BOOLEAN)
add_subdirectory(bsp)
endif()

View File

@ -6,9 +6,7 @@ SConscript(['audaspace/SConscript',
'ghost/SConscript',
'guardedalloc/SConscript',
'moto/SConscript',
'container/SConscript',
'memutil/SConscript/',
'decimation/SConscript',
'iksolver/SConscript',
'itasc/SConscript',
'opencolorio/SConscript',
@ -17,6 +15,9 @@ SConscript(['audaspace/SConscript',
'smoke/SConscript',
'raskter/SConscript'])
# currently only contains headers
# SConscript('container/SConscript')
if env ['WITH_BF_REMESH']:
SConscript(['dualcon/SConscript'])

View File

@ -33,14 +33,9 @@ set(INC_SYS
)
set(SRC
intern/CTR_List.cpp
CTR_HashedPtr.h
CTR_List.h
CTR_Map.h
CTR_TaggedIndex.h
CTR_TaggedSetOps.h
CTR_UHeap.h
)
# infact nothing to compile!
blender_add_lib(bf_intern_ctr "${SRC}" "${INC}" "${INC_SYS}")

View File

@ -30,8 +30,8 @@
* \ingroup ctr
*/
#ifndef CTR_HASHEDPTR_H
#define CTR_HASHEDPTR_H
#ifndef __CTR_HASHEDPTR_H__
#define __CTR_HASHEDPTR_H__
#include <stdlib.h>
@ -51,5 +51,5 @@ public:
void *getValue() const { return m_valptr; }
};
#endif //CTR_HASHEDPTR_H
#endif /* __CTR_HASHEDPTR_H__ */

View File

@ -1,112 +0,0 @@
/*
* ***** BEGIN GPL LICENSE BLOCK *****
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software Foundation,
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*
* The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
* All rights reserved.
*
* The Original Code is: all of this file.
*
* Contributor(s): none yet.
*
* ***** END GPL LICENSE BLOCK *****
*/
/** \file container/CTR_List.h
* \ingroup ctr
*/
#ifndef CTR_LIST_H
#define CTR_LIST_H
class CTR_Link {
public:
CTR_Link(
);
CTR_Link(
CTR_Link *next,
CTR_Link *prev
);
CTR_Link *
getNext(
) const;
CTR_Link *
getPrev(
) const;
bool
isHead(
) const;
bool
isTail(
) const;
void
insertBefore(
CTR_Link *link
);
void
insertAfter(
CTR_Link *link
);
void
remove(
);
private:
CTR_Link *m_next;
CTR_Link *m_prev;
};
class CTR_List {
public:
CTR_List(
);
CTR_Link *
getHead(
) const;
CTR_Link *
getTail(
) const;
void
addHead(
CTR_Link *link
);
void
addTail(
CTR_Link *link
);
private:
CTR_Link m_head;
CTR_Link m_tail;
};
#endif

View File

@ -29,9 +29,8 @@
* \ingroup ctr
*/
#ifndef CTR_MAP_H
#define CTR_MAP_H
#ifndef __CTR_MAP_H__
#define __CTR_MAP_H__
template <class Key, class Value>
class CTR_Map {
@ -177,5 +176,4 @@ private:
Entry **m_buckets;
};
#endif
#endif /* __CTR_MAP_H__ */

View File

@ -1,219 +0,0 @@
/*
* ***** BEGIN GPL LICENSE BLOCK *****
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software Foundation,
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*
* The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
* All rights reserved.
*
* The Original Code is: all of this file.
*
* Contributor(s): none yet.
*
* ***** END GPL LICENSE BLOCK *****
*/
/** \file container/CTR_TaggedIndex.h
* \ingroup ctr
*/
/**
* Copyright (C) 2001 NaN Technologies B.V.
* Simple tagged index class.
*/
#ifndef __CTR_TAGGEDINDEX_H__
#define __CTR_TAGGEDINDEX_H__
/**
* This class is supposed to be a simple tagged index class. If these
* were indices into a mesh then we would never need 32 bits for such indices.
* It is often handy to have a few extra bits around to mark objects etc. We
* steal a few bits of CTR_TaggedIndex objects for this purpose. From the outside
* it will behave like a standard unsigned int but just carry the extra tag
* information around with it.
*/
#include <functional>
#include "MEM_sys_types.h"
enum {
empty_tag = 0x0,
empty_index = 0xffffffff
};
template <
int tag_shift,
int index_mask
> class CTR_TaggedIndex {
public:
CTR_TaggedIndex(
) :
m_val ((empty_tag << tag_shift) | (empty_index & index_mask))
{
}
CTR_TaggedIndex(
const int val
) :
m_val ((val & index_mask) | ((empty_tag << tag_shift) & (~index_mask))) {
}
CTR_TaggedIndex(
const unsigned int val
) :
m_val ((val & index_mask) | ((empty_tag << tag_shift) & (~index_mask))) {
}
CTR_TaggedIndex(
const long int val
) :
m_val ( ((long int) val & index_mask)
| ( (empty_tag << tag_shift)
& (~index_mask)) ) {
}
CTR_TaggedIndex(
const long unsigned int val
) :
m_val ( ((long unsigned int)val & index_mask)
| ( (empty_tag << tag_shift)
& (~index_mask) ) ) {
}
#if defined(_WIN64)
CTR_TaggedIndex(
const uint64_t val
) :
m_val ( ((uint64_t)val & index_mask)
| ( (empty_tag << tag_shift)
& (~index_mask) ) ) {
}
#endif
CTR_TaggedIndex(
const CTR_TaggedIndex &my_index
):
m_val(my_index.m_val)
{
}
bool
operator == (
const CTR_TaggedIndex& rhs
) const {
return ((this->m_val & index_mask) == (rhs.m_val & index_mask));
}
operator unsigned int () const {
return m_val & index_mask;
}
operator unsigned long int () const {
return (unsigned long int)(m_val & index_mask);
}
operator int () const {
return int(m_val & index_mask);
}
operator long int () const {
return (long int)(m_val & index_mask);
}
#if defined(_WIN64)
operator uint64_t () const {
return (uint64_t)(m_val & index_mask);
}
#endif
bool
IsEmpty(
) const {
return ((m_val & index_mask) == (empty_index & index_mask));
}
static
CTR_TaggedIndex
Empty(
) {
return CTR_TaggedIndex();
}
void
Invalidate(
) {
m_val = (empty_tag << tag_shift) | (empty_index & index_mask);
}
unsigned int
Tag (
) const {
return m_val >> tag_shift;
}
void
SetTag(
unsigned int tag
) {
m_val = (m_val & index_mask) | ((tag << tag_shift) & (~index_mask));
}
void
EmptyTag(
) {
m_val = (m_val & index_mask) | ((empty_tag << tag_shift) & (~index_mask));
}
bool
IsEmptyTag(
) const {
return (Tag() == Empty().Tag());
}
// functionals
struct greater : std::binary_function<CTR_TaggedIndex, CTR_TaggedIndex, bool>
{
bool
operator()(
const CTR_TaggedIndex& a,
const CTR_TaggedIndex& b
) const {
return (int(a) > int(b));
}
};
private :
CTR_TaggedIndex(
const CTR_TaggedIndex *index
) {};
unsigned int m_val;
};
#endif

View File

@ -1,301 +0,0 @@
/*
* ***** BEGIN GPL LICENSE BLOCK *****
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software Foundation,
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*
* The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
* All rights reserved.
*
* The Original Code is: all of this file.
*
* Contributor(s): none yet.
*
* ***** END GPL LICENSE BLOCK *****
*/
/** \file container/CTR_TaggedSetOps.h
* \ingroup ctr
*/
#ifndef __CTR_TAGGEDSETOPS_H__
#define __CTR_TAGGEDSETOPS_H__
#include "MEM_NonCopyable.h"
#include <vector>
/**
* This class contains some utility functions for finding the intersection,
* union, and difference of a collection of stl vector of indices into
* a set of primitives.
*
* These are mainly used as helper functions in the decimation and bsp
* libraries.
*
* This template class assumes that each value of type IndexType encountered
* in the list is a valid index into an array of primitives. This is not
* checked at run-time and is left to the user to insure. Prmitives of
* type ObjectType must have the following public methods to be used by
* this template class:
*
* int
* OpenTag(void) --- return a persistent tag value for the primitive
*
* void
* SetOpenTag(int bla) --- set the persistent tag value for this primitive to bla.
*
* bool
* SelectTag() --- return a persistent boolean tag for this primitive
*
* void
* SetSelectTag(bool bla) --- set the persistent boolean tag for this primitive to bla.
*
* Here persistent means that the tag should be associated with the object for the
* entire lifetime of the primitive. Again none of this stuff is enforced you have
* to make sure that your primitives do the right thing. Often these tags can be
* cunningly stowed away inside some of the spare bits in the primitive. See
* CTR_TaggedIndex for such a class.
*
*/
template
<class IndexType, class ObjectType>
class CTR_TaggedSetOps : public MEM_NonCopyable {
public :
static
void
Intersect(
const std::vector< std::vector<IndexType> > &index_list,
std::vector<ObjectType> &primitives,
std::vector<IndexType> &output,
unsigned int mask,
unsigned int shift
) {
// iterate through vectors in index_list
// iterate through individual members of each vector
// mark each obejct that the index points to
typename std::vector< std::vector<IndexType> >::const_iterator
last_vector = index_list.end();
typename std::vector< std::vector<IndexType> >::const_iterator
start_vector = index_list.begin();
// FIXME some temporary space
std::vector<IndexType> temp_union;
temp_union.reserve(64);
int tag_num = 0;
for (; start_vector != last_vector; ++start_vector) {
typename std::vector<IndexType>::const_iterator
last_index = start_vector->end();
typename std::vector<IndexType>::const_iterator
start_index = start_vector->begin();
for (; start_index != last_index; ++start_index) {
ObjectType & prim = primitives[*start_index];
if (!prim.OpenTag()) {
// compute the union
temp_union.push_back(*start_index);
}
int tag = prim.OpenTag();
tag = (tag & mask) >> shift;
tag += 1;
prim.SetOpenTag((prim.OpenTag() & ~mask)| ((tag << shift) & mask));
}
++tag_num;
}
// now iterate through the union and pull out all those with the right tag
typename std::vector<IndexType>::const_iterator last_index =
temp_union.end();
typename std::vector<IndexType>::const_iterator start_index =
temp_union.begin();
for (; start_index != last_index; ++start_index) {
ObjectType & prim = primitives[*start_index];
if (prim.OpenTag() == tag_num) {
//it's part of the intersection!
output.push_back(*start_index);
// because we're iterating through the union
// it's safe to remove the tag at this point
prim.SetOpenTag(prim.OpenTag() & ~mask);
}
}
};
// note not a strict set intersection!
// if x appears twice in b and is part of the intersection
// it will appear twice in the intersection
static
void
IntersectPair(
const std::vector<IndexType> &a,
const std::vector<IndexType> &b,
std::vector<ObjectType> &primitives,
std::vector<IndexType> &output
) {
typename std::vector<IndexType>::const_iterator last_index =
a.end();
typename std::vector<IndexType>::const_iterator start_index =
a.begin();
for (; start_index != last_index; ++start_index) {
ObjectType & prim = primitives[*start_index];
prim.SetSelectTag(true);
}
last_index = b.end();
start_index = b.begin();
for (; start_index != last_index; ++start_index) {
ObjectType & prim = primitives[*start_index];
if (prim.SelectTag()) {
output.push_back(*start_index);
}
}
// deselect
last_index = a.end();
start_index = a.begin();
for (; start_index != last_index; ++start_index) {
ObjectType & prim = primitives[*start_index];
prim.SetSelectTag(false);
}
};
static
void
Union(
std::vector< std::vector<IndexType> > &index_list,
std::vector<ObjectType> &primitives,
std::vector<IndexType> &output
) {
// iterate through vectors in index_list
// iterate through individual members of each vector
// mark each obejct that the index points to
typename std::vector< std::vector<IndexType> >::const_iterator
last_vector = index_list.end();
typename std::vector< std::vector<IndexType> >::iterator
start_vector = index_list.begin();
for (; start_vector != last_vector; ++start_vector) {
typename std::vector<IndexType>::const_iterator
last_index = start_vector->end();
typename std::vector<IndexType>::iterator
start_index = start_vector->begin();
for (; start_index != last_index; ++start_index) {
ObjectType & prim = primitives[*start_index];
if (!prim.SelectTag()) {
// compute the union
output.push_back(*start_index);
prim.SetSelectTag(true);
}
}
}
// now iterate through the union and reset the tags
typename std::vector<IndexType>::const_iterator last_index =
output.end();
typename std::vector<IndexType>::iterator start_index =
output.begin();
for (; start_index != last_index; ++start_index) {
ObjectType & prim = primitives[*start_index];
prim.SetSelectTag(false);
}
}
static
void
Difference(
std::vector< IndexType> &a,
std::vector< IndexType> &b,
std::vector<ObjectType> &primitives,
std::vector< IndexType> &output
) {
// iterate through b mark all
// iterate through a and add to output all unmarked
typename std::vector<IndexType>::const_iterator last_index =
b.end();
typename std::vector<IndexType>::iterator start_index =
b.begin();
for (; start_index != last_index; ++start_index) {
ObjectType & prim = primitives[*start_index];
prim.SetSelectTag(true);
}
last_index = a.end();
start_index = a.begin();
for (; start_index != last_index; ++start_index) {
ObjectType & prim = primitives[*start_index];
if (!prim.SelectTag()) {
output.push_back(*start_index);
}
}
// clean up the tags
last_index = b.end();
start_index = b.begin();
for (; start_index != last_index; ++start_index) {
ObjectType & prim = primitives[*start_index];
prim.SetSelectTag(false);
}
};
private :
// private constructor - this class is not meant for
// instantiation
CTR_TaggedSetOps();
};
#endif

View File

@ -1,307 +0,0 @@
/*
* ***** BEGIN GPL LICENSE BLOCK *****
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software Foundation,
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*
* The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
* All rights reserved.
*
* The Original Code is: all of this file.
*
* Contributor(s): none yet.
*
* ***** END GPL LICENSE BLOCK *****
*/
/** \file container/CTR_UHeap.h
* \ingroup ctr
*/
/**
* Copyright (C) 2001 NaN Technologies B.V.
*
* @author Laurence
* @mainpage CTR_UHeap an updatable heap template class (also
* known as an updatable priority queue)
*
* Todo: Make CTR_UHeapable a template class with m_key the
* template parameter, so that arbitrary value types with
* operators (=,>) defined can be used.
*
*/
#ifndef __CTR_UHEAP_H__
#define __CTR_UHEAP_H__
#include <vector>
#include "MEM_NonCopyable.h"
class CTR_UHeapable {
public:
int &
HeapPos(
) {
return m_ind;
};
float &
HeapKey(
) {
return m_key;
};
const
float &
HeapKey(
) const {
return m_key;
};
const
int &
HeapPos(
) const {
return m_ind;
};
private:
float m_key;
int m_ind;
protected:
CTR_UHeapable(
) : m_key(0),
m_ind(0)
{
};
~CTR_UHeapable(
) {
};
};
template <class HeapType>
class CTR_UHeap : public MEM_NonCopyable
{
public:
static
CTR_UHeap *
New(
) {
return new CTR_UHeap();
}
void
MakeHeap(
HeapType *base
) {
int i;
int start = Parent(m_vector.size() - 1);
for (i = start; i >= 0; --i) {
DownHeap(base, i);
}
};
void
Insert(
HeapType *base,
int elem
) {
// add element to vector
m_vector.push_back(elem);
base[elem].HeapPos() = m_vector.size() - 1;
// push the element up the heap
UpHeap(base, m_vector.size() - 1);
}
// access to the vector for initial loading of elements
std::vector<int> &
HeapVector(
) {
return m_vector;
};
void
Remove(
HeapType *base,
int i
) {
// exchange with last element - pop last
// element and move up or down the heap as appropriate
if (m_vector.empty()) {
assert(false);
}
if (i != int(m_vector.size()) - 1) {
Swap(base, i, m_vector.size() - 1);
m_vector.pop_back();
if (!m_vector.empty()) {
UpHeap(base, i);
DownHeap(base, i);
}
}
else {
m_vector.pop_back();
}
}
int
Top(
) const {
if (m_vector.empty()) return -1;
return m_vector[0];
}
void
SC_Heap(
HeapType *base
) {
int i;
for (i = 1; i < int(m_vector.size()); i++) {
CTR_UHeapable *elem = base + m_vector[i];
CTR_UHeapable *p_elem = base + m_vector[Parent(i)];
assert(p_elem->HeapKey() >= elem->HeapKey());
assert(elem->HeapPos() == i);
}
};
~CTR_UHeap(
) {
};
private:
CTR_UHeap(
) {
};
std::vector<int> m_vector;
private:
void
Swap(
HeapType *base,
int i,
int j
) {
std::swap(m_vector[i], m_vector[j]);
CTR_UHeapable *heap_i = base + m_vector[i];
CTR_UHeapable *heap_j = base + m_vector[j];
// Exchange heap positions
heap_i->HeapPos() = i;
heap_j->HeapPos() = j;
}
int
Parent(
unsigned int i
) {
return (i - 1) >> 1;
}
int
Left(
int i
) {
return (i << 1) + 1;
}
int
Right(
int i
) {
return (i << 1) + 2;
}
float
HeapVal(
HeapType *base,
int i
) {
return base[m_vector[i]].HeapKey();
}
void
DownHeap(
HeapType *base,
int i
) {
int heap_size = m_vector.size();
int l = Left(i);
int r = Right(i);
int largest;
if (l < heap_size && HeapVal(base, l) > HeapVal(base, i)) {
largest = l;
}
else {
largest = i;
}
if (r < heap_size && HeapVal(base, r) > HeapVal(base, largest)) {
largest = r;
}
if (largest != i) {
// exchange i and largest
Swap(base, i, largest);
DownHeap(base, largest);
}
}
void
UpHeap(
HeapType *base,
int i
) {
// swap parents untill it's found a place in the heap < it's parent or
// top of heap
while (i > 0) {
int p = Parent(i);
if (HeapVal(base, i) < HeapVal(base, p)) {
break;
}
Swap(base, p, i);
i = p;
}
}
};
#endif

View File

@ -1,127 +0,0 @@
/*
* ***** BEGIN GPL LICENSE BLOCK *****
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software Foundation,
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*
* The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
* All rights reserved.
*
* The Original Code is: all of this file.
*
* Contributor(s): none yet.
*
* ***** END GPL LICENSE BLOCK *****
*/
/** \file container/intern/CTR_List.cpp
* \ingroup ctr
*/
#include "CTR_List.h"
CTR_Link::CTR_Link() :
m_next(0),
m_prev(0)
{
}
CTR_Link::CTR_Link(CTR_Link *next, CTR_Link *prev) :
m_next(next),
m_prev(prev)
{
}
CTR_Link *
CTR_Link::getNext() const
{
return m_next;
}
CTR_Link *
CTR_Link::getPrev() const
{
return m_prev;
}
bool
CTR_Link::isHead() const
{
return m_prev == 0;
}
bool
CTR_Link::isTail() const
{
return m_next == 0;
}
void
CTR_Link::insertBefore(CTR_Link *link)
{
m_next = link;
m_prev = link->m_prev;
m_next->m_prev = this;
m_prev->m_next = this;
}
void
CTR_Link::insertAfter(CTR_Link *link)
{
m_next = link->m_next;
m_prev = link;
m_next->m_prev = this;
m_prev->m_next = this;
}
void
CTR_Link::remove()
{
m_next->m_prev = m_prev;
m_prev->m_next = m_next;
}
CTR_List::CTR_List() :
m_head(&m_tail, 0),
m_tail(0, &m_head)
{
}
CTR_Link *
CTR_List:: getHead() const
{
return m_head.getNext();
}
CTR_Link *
CTR_List::getTail() const
{
return m_tail.getPrev();
}
void
CTR_List::addHead(CTR_Link *link)
{
link->insertAfter(&m_head);
}
void
CTR_List::addTail(CTR_Link *link)
{
link->insertBefore(&m_tail);
}

View File

@ -1,63 +0,0 @@
# ***** BEGIN GPL LICENSE BLOCK *****
#
# This program is free software; you can redistribute it and/or
# modify it under the terms of the GNU General Public License
# as published by the Free Software Foundation; either version 2
# of the License, or (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software Foundation,
# Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
#
# The Original Code is Copyright (C) 2006, Blender Foundation
# All rights reserved.
#
# The Original Code is: all of this file.
#
# Contributor(s): Jacques Beaurain.
#
# ***** END GPL LICENSE BLOCK *****
set(INC
.
../container
../guardedalloc
../memutil
../moto/include
)
set(INC_SYS
)
set(SRC
intern/LOD_EdgeCollapser.cpp
intern/LOD_ExternNormalEditor.cpp
intern/LOD_FaceNormalEditor.cpp
intern/LOD_ManMesh2.cpp
intern/LOD_MeshPrimitives.cpp
intern/LOD_QSDecimator.cpp
intern/LOD_QuadricEditor.cpp
intern/LOD_decimation.cpp
extern/LOD_decimation.h
intern/LOD_DecimationClass.h
intern/LOD_EdgeCollapser.h
intern/LOD_ExternBufferEditor.h
intern/LOD_ExternNormalEditor.h
intern/LOD_FaceNormalEditor.h
intern/LOD_ManMesh2.h
intern/LOD_MeshBounds.h
intern/LOD_MeshException.h
intern/LOD_MeshPrimitives.h
intern/LOD_QSDecimator.h
intern/LOD_Quadric.h
intern/LOD_QuadricEditor.h
)
blender_add_lib(bf_intern_decimate "${SRC}" "${INC}" "${INC_SYS}")

View File

@ -1,8 +0,0 @@
#!/usr/bin/python
Import ('env')
sources = env.Glob('intern/*.cpp')
incs = '. ../moto/include ../container ../memutil ../guardedalloc'
env.BlenderLib ('bf_intern_decimate', sources, Split(incs) , [], libtype=['core', 'player'], priority = [200, 100] )

View File

@ -1,117 +0,0 @@
/*
* ***** BEGIN GPL LICENSE BLOCK *****
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software Foundation,
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*
* The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
* All rights reserved.
*
* The Original Code is: all of this file.
*
* Contributor(s): none yet.
*
* ***** END GPL LICENSE BLOCK *****
*/
/** \file decimation/extern/LOD_decimation.h
* \ingroup decimation
*/
/**
* @author Laurence Bourn
* @date 6/7/2001
*
* This is the external interface for the decimation module.
*/
#ifndef __LOD_DECIMATION_H__
#define __LOD_DECIMATION_H__
#ifdef __cplusplus
extern "C" {
#endif
/**
* External decimation structure
*/
typedef struct LOD_Decimation_Info {
float * vertex_buffer;
float * vertex_normal_buffer;
int * triangle_index_buffer;
int vertex_num;
int face_num;
void * intern;
} LOD_Decimation_Info;
typedef LOD_Decimation_Info* LOD_Decimation_InfoPtr;
/**
* Create internal mesh representation from
* LOD_Decimation_Info structure.
* @return 1 on successful loading
* @return 0 on failure
* @warning This should be changed to return an enumeration
* detailing the error encountered
*/
extern int LOD_LoadMesh(LOD_Decimation_InfoPtr info);
/**
* Allocate and Compute internal data strucures required for
* decimation.
* @return 1 on successful computation of data
* @return 0 on failure
* @warning This should be changed to return an enumeration
* detailing the error encountered
*/
extern int LOD_PreprocessMesh(LOD_Decimation_InfoPtr info);
/**
* Once both the stages above have been completed
* this function collapses a single edge in the mesh.
* The LOD_Decimation_Info structure is updated
* to represent the new mesh.
* @return 1 if an edge was collapsed.
* @return 0 if no suitable edge was found to be collapsable
* You should stop calling this method in this case
* @warning Do not expect that the order of polygons, vertices or
* vertex normals will be preserved by this operation. This function
* returns a packed array of polygons and vertices and so necessarily
* the order will be different. This means you should not expect to
* find the same polygon in the same place in the polygon array after
* this function has been called.
*/
extern int LOD_CollapseEdge(LOD_Decimation_InfoPtr info);
/**
* Free any memory the decimation process used
* during the decimation process
* @return 1 if internal data successfully freed
* @return 0 if no data was freed
*/
extern int LOD_FreeDecimationData(LOD_Decimation_InfoPtr);
#ifdef __cplusplus
}
#endif
#endif // __LOD_DECIMATION_H__

View File

@ -1,118 +0,0 @@
/*
* ***** BEGIN GPL LICENSE BLOCK *****
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software Foundation,
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*
* The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
* All rights reserved.
*
* The Original Code is: all of this file.
*
* Contributor(s): none yet.
*
* ***** END GPL LICENSE BLOCK *****
*/
/** \file decimation/intern/LOD_DecimationClass.h
* \ingroup decimation
*/
#ifndef __LOD_DECIMATIONCLASS_H__
#define __LOD_DECIMATIONCLASS_H__
#include "MEM_SmartPtr.h"
#include "MEM_NonCopyable.h"
#include "LOD_ManMesh2.h"
#include "LOD_QSDecimator.h"
#include "LOD_ExternNormalEditor.h"
#include "../extern/LOD_decimation.h"
#include "LOD_ExternBufferEditor.h"
class LOD_DecimationClass : public MEM_NonCopyable
{
public :
enum {
e_not_loaded,
e_loaded,
e_preprocessed
} m_e_decimation_state;
static
LOD_DecimationClass *
New(
LOD_Decimation_InfoPtr extern_info
) {
// create everything
MEM_SmartPtr<LOD_DecimationClass> output(new LOD_DecimationClass());
MEM_SmartPtr<LOD_ManMesh2> mesh(LOD_ManMesh2::New());
MEM_SmartPtr<LOD_ExternBufferEditor> extern_editor(LOD_ExternBufferEditor::New(extern_info));
if (mesh == NULL || extern_editor == NULL) return NULL;
MEM_SmartPtr<LOD_ExternNormalEditor> normals(LOD_ExternNormalEditor::New(extern_info,mesh.Ref()));
if (normals == NULL) return NULL;
MEM_SmartPtr<LOD_QSDecimator> decimator(LOD_QSDecimator::New(
mesh.Ref(),
normals.Ref(),
extern_editor.Ref()
));
if (decimator == NULL || output == NULL) return NULL;
output->m_mesh = mesh.Release();
output->m_decimator = decimator.Release();
output->m_normals = normals.Release();
output->m_extern_editor = extern_editor.Release();
return output.Release();
}
LOD_ManMesh2 &
Mesh(
){
return m_mesh.Ref();
}
LOD_QSDecimator &
Decimator(
) {
return m_decimator.Ref();
}
LOD_ExternNormalEditor &
FaceEditor(
){
return m_normals.Ref();
}
private :
LOD_DecimationClass(
) : m_e_decimation_state(e_not_loaded) {
};
MEM_SmartPtr<LOD_ManMesh2> m_mesh;
MEM_SmartPtr<LOD_QSDecimator> m_decimator;
MEM_SmartPtr<LOD_ExternNormalEditor> m_normals;
MEM_SmartPtr<LOD_ExternBufferEditor> m_extern_editor;
};
#endif

View File

@ -1,410 +0,0 @@
/*
* ***** BEGIN GPL LICENSE BLOCK *****
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software Foundation,
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*
* The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
* All rights reserved.
*
* The Original Code is: all of this file.
*
* Contributor(s): none yet.
*
* ***** END GPL LICENSE BLOCK *****
*/
/** \file decimation/intern/LOD_EdgeCollapser.cpp
* \ingroup decimation
*/
#include "LOD_EdgeCollapser.h"
#include "LOD_ManMesh2.h"
#include "CTR_TaggedSetOps.h"
#include <algorithm>
#include <functional>
using namespace std;
LOD_EdgeCollapser *
LOD_EdgeCollapser::
New(
){
return new LOD_EdgeCollapser();
}
bool
LOD_EdgeCollapser::
TJunctionTest(
LOD_ManMesh2 &mesh,
vector<LOD_EdgeInd> &e_v0v1,
LOD_EdgeInd collapse_edge
){
// we need to copy the edges in e_v0v1 from the mesh
// into a new buffer -> we are going to modify them
int original_size = e_v0v1.size();
if (original_size == 0) return true;
vector<LOD_Edge> &edge_set = mesh.EdgeSet();
LOD_VertexInd c_v0 = edge_set[collapse_edge].m_verts[0];
LOD_VertexInd c_v1 = edge_set[collapse_edge].m_verts[1];
vector<LOD_Edge> temp_edges;
temp_edges.reserve(e_v0v1.size());
vector<LOD_EdgeInd>::iterator edge_it = e_v0v1.begin();
vector<LOD_EdgeInd>::const_iterator edge_end = e_v0v1.end();
for (;edge_it != edge_end; ++edge_it) {
temp_edges.push_back(edge_set[*edge_it]);
}
// in the copied edges replace all instances of c_v0 with c_v1
vector<LOD_Edge>::iterator e_it = temp_edges.begin();
vector<LOD_Edge>::const_iterator e_it_end = temp_edges.end();
for (; e_it != e_it_end; ++e_it) {
if (e_it->m_verts[0] == c_v0) {
e_it->m_verts[0] = c_v1;
}
if (e_it->m_verts[1] == c_v0) {
e_it->m_verts[1] = c_v1;
}
// normalize the edge
if (int(e_it->m_verts[0]) > int(e_it->m_verts[1])) {
LOD_EdgeInd temp = e_it->m_verts[0];
e_it->m_verts[0] = e_it->m_verts[1];
e_it->m_verts[1] = temp;
}
}
// sort the edges using the edge less functional
sort(temp_edges.begin(),temp_edges.end(),LOD_EdgeCollapser::less());
// count the unique edges.
e_it = temp_edges.begin();
e_it_end = temp_edges.end();
int coincedent_edges = 0;
vector<LOD_Edge>::const_iterator last_edge = e_it;
++e_it;
for (; e_it != e_it_end; ++e_it) {
if ((e_it->m_verts[0] == last_edge->m_verts[0]) &&
(e_it->m_verts[1] == last_edge->m_verts[1])
) {
++coincedent_edges;
}
last_edge = e_it;
}
// now if the collapse edge is a boundary edges
// then we are alloved at most one coincedent edge
// otherwise at most 2 coincedent edges
if (edge_set[collapse_edge].BoundaryEdge()) {
return (coincedent_edges > 1);
} else {
return (coincedent_edges > 2);
}
}
bool
LOD_EdgeCollapser::
CollapseEdge(
LOD_EdgeInd ei,
LOD_ManMesh2 &mesh,
vector<LOD_EdgeInd> & degenerate_edges,
vector<LOD_FaceInd> & degenerate_faces,
vector<LOD_VertexInd> & degenerate_vertices,
vector<LOD_EdgeInd> & new_edges,
vector<LOD_FaceInd> & update_faces,
vector<LOD_VertexInd> & update_vertices
){
vector<LOD_Vertex> &verts = mesh.VertexSet();
vector<LOD_Edge> &edges = mesh.EdgeSet();
vector<LOD_TriFace> &faces = mesh.FaceSet();
// shouldn't do this (use mesh interface instead!)
LOD_VertexInd v0_ind = edges[ei].m_verts[0];
LOD_VertexInd v1_ind = edges[ei].m_verts[1];
#if 0
LOD_Vertex &v0 = verts[v0_ind];
LOD_Vertex &v1 = verts[v1_ind];
#endif
vector<vector<LOD_EdgeInd> > e_v01(2);
e_v01[0].reserve(32);
e_v01[1].reserve(32);
mesh.VertexEdges(v0_ind,e_v01[0]);
mesh.VertexEdges(v1_ind,e_v01[1]);
// compute the union of e_v0 and e_v1 -> this is the degenerate edges of the collapse
// we remove old edges and replace edges inside the collapse zone with new ones
CTR_TaggedSetOps<LOD_EdgeInd,LOD_Edge>::Union(e_v01,edges,degenerate_edges);
vector< vector<LOD_FaceInd> > p_v01(2);
p_v01[0].reserve(32);
p_v01[1].reserve(32);
mesh.VertexFaces(v0_ind,p_v01[0]);
mesh.VertexFaces(v1_ind,p_v01[1]);
// compute the union of p_v0 anf p_v1
vector<LOD_FaceInd> p_v0v1;
p_v0v1.reserve(32);
CTR_TaggedSetOps<LOD_FaceInd,LOD_TriFace>::Union(p_v01,faces,p_v0v1);
// compute the union of all the edges in p_v0v1 this is the collapse zone
vector<vector<LOD_EdgeInd> > e_input_vectors(p_v0v1.size());
vector<LOD_FaceInd>::iterator p_v0v1_end = p_v0v1.end();
vector<LOD_FaceInd>::iterator p_v0v1_start = p_v0v1.begin();
vector<vector<LOD_FaceInd> >::iterator vector_insert_it = e_input_vectors.begin();
for (;p_v0v1_start != p_v0v1_end; ++p_v0v1_start , ++vector_insert_it) {
mesh.FaceEdges(*p_v0v1_start,*vector_insert_it);
}
vector<LOD_EdgeInd> collapse_zone;
collapse_zone.reserve(32);
CTR_TaggedSetOps<LOD_EdgeInd,LOD_Edge>::Union(e_input_vectors,edges,collapse_zone);
// compute the ring edges = collpase_zone - e_v0v1
vector<LOD_EdgeInd> edge_ring;
edge_ring.reserve(32);
CTR_TaggedSetOps<LOD_EdgeInd,LOD_Edge>::Difference(collapse_zone,degenerate_edges,edges,edge_ring);
// T Junction test
//////////////////
// At this point we check to see if any of the polygons
// in p_v0v1 are coninceddent - this leads
// to errors later on if we try and insert a polygon
// into the mesh to an edge which already has 2 polygons.
// not that t junctions occur naturally from edge collapses
// and are not just the result of coincedent polygons
// for example consider collapsing an edge that forms part
// of a triangular bottle neck.
// Really we need to make sure that we don't create t-junctions.
// I think that a sufficient test is to check the number of
// coincedent edge pairs after a collapse. If it is more than 2
// then collapsing the edge may result in an undeleted edge
// sharing more than 2 polygons. This test probably is too
// restictive though.
// To perform this test we need to make a copy of the edges
// in e_v0v1. We then apply the contraction to these edge
// copies. Sort them using a function that places coincedent
// edges next to each other. And then count the number
// of coincedent pairs.
// Of course we have to do this test before we change any of the
// mesh -> so we can back out safely.
if (TJunctionTest(mesh,degenerate_edges,ei)) return false;
// Compute the set of possibly degenerate vertices
// this is the union of all the vertices of polygons
// of v0 and v1
vector<LOD_FaceInd>::iterator face_it = p_v0v1.begin();
vector<LOD_FaceInd>::const_iterator face_end = p_v0v1.end();
vector<vector<LOD_VertexInd> > p_v0v1_vertices(p_v0v1.size());
for (int i = 0; face_it != face_end; ++face_it, ++i) {
mesh.FaceVertices(*face_it,p_v0v1_vertices[i]);
}
vector<LOD_VertexInd> vertex_ring;
vertex_ring.reserve(32);
CTR_TaggedSetOps<LOD_VertexInd,LOD_Vertex>::Union(p_v0v1_vertices,verts,vertex_ring);
// remove all the internal edges e_v0v1 from the mesh.
// for each edge remove the egde from it's vertices edge lists.
vector<LOD_EdgeInd>::iterator edge_it = degenerate_edges.begin();
vector<LOD_EdgeInd>::const_iterator edge_end = degenerate_edges.end();
for (; !(edge_it == edge_end); ++edge_it) {
LOD_EdgeInd ed = (*edge_it);
LOD_Edge & edge = edges[ed];//*edge_it];
verts[edge.m_verts[0]].RemoveEdge(ed);
verts[edge.m_verts[1]].RemoveEdge(ed);
}
// we postpone deletion of the internal edges untill the end
// this is because deleting edges invalidates all of the
// EdgeInd vectors above.
// now untie all the polygons in p_v0v1 from the edge ring
// select all polygons in p_v0v1
face_it = p_v0v1.begin();
face_end = p_v0v1.end();
for (;face_it != face_end; ++face_it) {
faces[*face_it].SetSelectTag(true);
}
edge_it = edge_ring.begin();
edge_end = edge_ring.end();
for (;edge_it != edge_end; ++edge_it) {
LOD_Edge & edge = edges[*edge_it];
// presumably all edges in edge_ring point to at least
// one polygon from p_v0v1
if (!edge.m_faces[0].IsEmpty() && faces[edge.m_faces[0]].SelectTag()) {
edge.m_faces[0].Invalidate();
}
if (!edge.m_faces[1].IsEmpty() && faces[edge.m_faces[1]].SelectTag()) {
edge.m_faces[1].Invalidate();
}
}
// deselect the faces
face_it = p_v0v1.begin();
face_end = p_v0v1.end();
for (;face_it != face_end; ++face_it) {
faces[*face_it].SetSelectTag(false);
}
// perform the edge collapse
////////////////////////////
// iterate through the polygons of p_v0 and replace the vertex
// index v0 with v1
face_it = p_v01[0].begin();
face_end = p_v01[0].end();
for (;face_it != face_end; ++face_it) {
faces[*face_it].SwapVertex(v0_ind,v1_ind);
}
face_it = p_v0v1.begin();
face_end = p_v0v1.end();
for (;face_it != face_end; ++face_it) {
if (faces[*face_it].Degenerate()) {
degenerate_faces.push_back(*face_it);
} else {
update_faces.push_back(*face_it);
}
}
// Add all the non-degenerate faces back into the
// mesh. Get a record of the new edges created in
// this process.
face_it = update_faces.begin();
face_end = update_faces.end();
for (;face_it != face_end; ++face_it) {
mesh.ConnectTriangle(*face_it,new_edges);
}
// degenerate ring primitives
/////////////////////////////
// we now need to examine each of the edges on the ring
// and work out if they are degenerate - if so we attempt
// to delete them -> add them to the other edges to delete
// in e_v0v1
edge_it = edge_ring.begin();
edge_end = edge_ring.end();
for (;edge_it != edge_end; ++edge_it) {
if (edges[*edge_it].Degenerate()) {
degenerate_edges.push_back(*edge_it);
}
}
// do the same for the ring vertices.
vector<LOD_VertexInd>::iterator vertex_it = vertex_ring.begin();
vector<LOD_VertexInd>::const_iterator vertex_end = vertex_ring.end();
for (;vertex_it != vertex_end; ++vertex_it) {
if (verts[*vertex_it].Degenerate()) {
degenerate_vertices.push_back(*vertex_it);
} else {
update_vertices.push_back(*vertex_it);
}
}
// we now know all the degenerate primitives
// and the new primitives we have inserted into the mesh
// We now delete the mesh primitives, mesh.DeleteXXXXXX() methods
// assume that the index vectors are sorted into descending order.
// we do that now.
sort(degenerate_edges.begin(),degenerate_edges.end(),LOD_EdgeInd::greater());
sort(degenerate_faces.begin(),degenerate_faces.end(),LOD_FaceInd::greater());
sort(degenerate_vertices.begin(),degenerate_vertices.end(),LOD_VertexInd::greater());
return true;
}
LOD_EdgeCollapser::
LOD_EdgeCollapser(
){
// nothing to do
}

View File

@ -1,117 +0,0 @@
/*
* ***** BEGIN GPL LICENSE BLOCK *****
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software Foundation,
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*
* The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
* All rights reserved.
*
* The Original Code is: all of this file.
*
* Contributor(s): none yet.
*
* ***** END GPL LICENSE BLOCK *****
*/
/** \file decimation/intern/LOD_EdgeCollapser.h
* \ingroup decimation
*/
#ifndef __LOD_EDGECOLLAPSER_H__
#define __LOD_EDGECOLLAPSER_H__
// This is a helper class that collapses edges of a 2 - manifold mesh.
#include "LOD_MeshPrimitives.h"
#include "MEM_NonCopyable.h"
#include <vector>
#include <functional>
class LOD_ManMesh2;
class LOD_EdgeCollapser
: public MEM_NonCopyable
{
public :
static
LOD_EdgeCollapser *
New(
);
// returns via arguments the set of modified
// verts,edges and faces.
bool
CollapseEdge(
LOD_EdgeInd ei,
LOD_ManMesh2 &mesh,
std::vector<LOD_EdgeInd> & degenerate_edges,
std::vector<LOD_FaceInd> & degenerate_faces,
std::vector<LOD_VertexInd> & degenerate_vertices,
std::vector<LOD_EdgeInd> & new_edges,
std::vector<LOD_FaceInd> & update_faces,
std::vector<LOD_VertexInd> & update_vertices
);
private :
LOD_EdgeCollapser(
);
// Test to see if the result of collapsing the
// edge produces 2 junctions in the mesh i.e. where
// an edge is shared by more than 2 polygons
// We count the number of coincedent edge pairs that
// result from the collapse of collapse_edge.
// If collapse edge is a boundary edge then the number of
// coincedent pairs should be 1
// else it should be 2.
bool
TJunctionTest(
LOD_ManMesh2 &mesh,
std::vector<LOD_EdgeInd> &e_v0v1,
LOD_EdgeInd collapse_edge
);
// here's the definition of the sort function
// we use to determine coincedent edges
// assumes the edges are normalized i.e. m_verts[0] <= m_verts[1]
struct less : std::binary_function<LOD_Edge, LOD_Edge, bool> {
bool
operator()(
const LOD_Edge& a,
const LOD_Edge& b
) const {
if (int(a.m_verts[0]) == int(b.m_verts[0])) {
return (int(a.m_verts[1]) < int(b.m_verts[1]));
} else {
return (int(a.m_verts[0]) < int(b.m_verts[0]));
}
}
};
};
#endif

View File

@ -1,164 +0,0 @@
/*
* ***** BEGIN GPL LICENSE BLOCK *****
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software Foundation,
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*
* The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
* All rights reserved.
*
* The Original Code is: all of this file.
*
* Contributor(s): none yet.
*
* ***** END GPL LICENSE BLOCK *****
*/
/** \file decimation/intern/LOD_ExternBufferEditor.h
* \ingroup decimation
*/
/**
* Copyright (C) 2001 NaN Technologies B.V.
*/
#ifndef __LOD_EXTERNBUFFEREDITOR_H__
#define __LOD_EXTERNBUFFEREDITOR_H__
#include "LOD_MeshPrimitives.h"
#include <vector>
#include "LOD_ManMesh2.h"
#include "../extern/LOD_decimation.h"
// This class syncs external vertex/face buffers
// with the internal mesh representation during
// decimation.
class LOD_ExternBufferEditor
{
public :
static
LOD_ExternBufferEditor *
New(
LOD_Decimation_InfoPtr extern_info
){
if (extern_info == NULL) return NULL;
return new LOD_ExternBufferEditor(extern_info);
}
// update the external vertex buffer with vertices
// from the mesh
void
CopyModifiedVerts(
LOD_ManMesh2 & mesh,
const std::vector<LOD_VertexInd> & mod_vertices
){
std::vector<LOD_VertexInd>::const_iterator v_start = mod_vertices.begin();
std::vector<LOD_VertexInd>::const_iterator v_end = mod_vertices.end();
std::vector<LOD_Vertex> & mesh_verts = mesh.VertexSet();
float * const extern_vertex_ptr = m_extern_info->vertex_buffer;
for (; v_start != v_end; ++v_start) {
float * mod_vert = extern_vertex_ptr + int(*v_start)*3;
mesh_verts[*v_start].CopyPosition(mod_vert);
}
}
// update the external face buffer with faces from the mesh
void
CopyModifiedFaces(
LOD_ManMesh2 & mesh,
const std::vector<LOD_FaceInd> & mod_faces
){
std::vector<LOD_FaceInd>::const_iterator f_start = mod_faces.begin();
std::vector<LOD_FaceInd>::const_iterator f_end = mod_faces.end();
std::vector<LOD_TriFace> &mesh_faces = mesh.FaceSet();
int * const extern_face_ptr = m_extern_info->triangle_index_buffer;
for (; f_start != f_end; ++f_start) {
int *mod_face = extern_face_ptr + 3*int(*f_start);
mesh_faces[*f_start].CopyVerts(mod_face);
}
}
// Copy the last vertex over the vertex specified by
// vi. Decrement the size of the vertex array
void
CopyBackVertex(
LOD_VertexInd vi
){
float * const extern_vertex_ptr = m_extern_info->vertex_buffer;
int * extern_vertex_num = &(m_extern_info->vertex_num);
float * last_external_vert = extern_vertex_ptr + 3*((*extern_vertex_num) - 1);
float * external_vert = extern_vertex_ptr + 3*int(vi);
external_vert[0] = last_external_vert[0];
external_vert[1] = last_external_vert[1];
external_vert[2] = last_external_vert[2];
*extern_vertex_num -=1;
}
// Copy the last face over the face specified by fi
// Decrement the size of the face array
void
CopyBackFace(
LOD_FaceInd fi
) {
int * const extern_face_ptr = m_extern_info->triangle_index_buffer;
int * extern_face_num = &(m_extern_info->face_num);
int * last_external_face = extern_face_ptr + 3*((*extern_face_num) -1);
int * external_face = extern_face_ptr + 3*int(fi);
external_face[0] = last_external_face[0];
external_face[1] = last_external_face[1];
external_face[2] = last_external_face[2];
*extern_face_num -=1;
}
private :
LOD_ExternBufferEditor(
LOD_Decimation_InfoPtr extern_info
) :
m_extern_info (extern_info)
{
}
LOD_Decimation_InfoPtr const m_extern_info;
};
#endif

View File

@ -1,264 +0,0 @@
/*
* ***** BEGIN GPL LICENSE BLOCK *****
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software Foundation,
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*
* The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
* All rights reserved.
*
* The Original Code is: all of this file.
*
* Contributor(s): none yet.
*
* ***** END GPL LICENSE BLOCK *****
*/
/** \file decimation/intern/LOD_ExternNormalEditor.cpp
* \ingroup decimation
*/
#include "LOD_ExternNormalEditor.h"
#include <vector>
using namespace std;
LOD_ExternNormalEditor::
LOD_ExternNormalEditor(
LOD_Decimation_InfoPtr extern_info,
LOD_ManMesh2 &mesh
) :
m_mesh(mesh),
m_extern_info (extern_info)
{
}
LOD_ExternNormalEditor *
LOD_ExternNormalEditor::
New(
LOD_Decimation_InfoPtr extern_info,
LOD_ManMesh2 &mesh
){
if (extern_info == NULL) return NULL;
MEM_SmartPtr<LOD_ExternNormalEditor> output(new LOD_ExternNormalEditor(extern_info,mesh));
int face_num = mesh.FaceSet().size();
MEM_SmartPtr<vector<MT_Vector3> > normals(new vector<MT_Vector3>);
if (output == NULL ||
normals == NULL
) {
return NULL;
}
normals->reserve(face_num);
output->m_normals = normals.Release();
return output.Release();
};
void
LOD_ExternNormalEditor::
Remove(
std::vector<LOD_FaceInd> &sorted_faces
){
// assumes a collection of faces sorted in descending order .
vector<MT_Vector3> & normals = m_normals.Ref();
vector<LOD_FaceInd>::const_iterator it_start = sorted_faces.begin();
vector<LOD_FaceInd>::const_iterator it_end = sorted_faces.end();
for (; it_start != it_end; ++it_start) {
if (normals.size() > 0) {
MT_Vector3 temp = normals[*it_start];
normals[*it_start] = normals.back();
normals.back() = temp;
normals.pop_back();
}
// FIXME - throw exception
}
}
void
LOD_ExternNormalEditor::
Add(
){
MT_Vector3 zero(0.0f,0.0f,0.0f);
m_normals->push_back(zero);
};
void
LOD_ExternNormalEditor::
Update(
std::vector<LOD_FaceInd> &sorted_faces
){
vector<MT_Vector3> & normals = m_normals.Ref();
vector<LOD_FaceInd>::const_iterator it_start = sorted_faces.begin();
vector<LOD_FaceInd>::const_iterator it_end = sorted_faces.end();
const vector<LOD_TriFace> &faces = m_mesh.FaceSet();
for (; it_start != it_end; ++it_start) {
normals[*it_start] = ComputeNormal(faces[*it_start]);
}
};
// vertex normals
/////////////////
void
LOD_ExternNormalEditor::
RemoveVertexNormals(
std::vector<LOD_VertexInd> &sorted_verts
){
float * vertex_normals = m_extern_info->vertex_normal_buffer;
// assumption here that the vertexs normal number corresponds with
// the number of vertices !
int vertex_normal_num = m_extern_info->vertex_num;
vector<LOD_VertexInd>::const_iterator it_start = sorted_verts.begin();
vector<LOD_VertexInd>::const_iterator it_end = sorted_verts.end();
for (; it_start != it_end; ++it_start) {
if (vertex_normal_num > 0) {
float * vertex_normal = vertex_normals + int(*it_start)*3;
float * last_vertex = vertex_normals + ((vertex_normal_num-1)*3);
MT_Vector3 last_v(last_vertex);
last_v.getValue(vertex_normal);
vertex_normal_num--;
}
// FIXME - through exception
}
};
void
LOD_ExternNormalEditor::
UpdateVertexNormals(
std::vector<LOD_VertexInd> &sorted_verts
){
float * vertex_normals = m_extern_info->vertex_normal_buffer;
vector<LOD_VertexInd>::const_iterator it_start = sorted_verts.begin();
vector<LOD_VertexInd>::const_iterator it_end = sorted_verts.end();
for (; it_start != it_end; ++it_start) {
MT_Vector3 temp = ComputeVertexNormal(*it_start);
float * vertex_normal = vertex_normals + int(*it_start)*3;
temp.getValue(vertex_normal);
}
}
// Editor specific methods
//////////////////////////
void
LOD_ExternNormalEditor::
BuildNormals(
) {
const vector<LOD_TriFace> &faces = m_mesh.FaceSet();
vector<MT_Vector3> & normals = m_normals.Ref();
int face_num = faces.size();
int cur_face = 0;
for (; cur_face < face_num; ++cur_face) {
MT_Vector3 new_normal = ComputeNormal(faces[cur_face]);
normals.push_back(new_normal);
}
}
const
MT_Vector3
LOD_ExternNormalEditor::
ComputeNormal(
const LOD_TriFace &face
) const {
const vector<LOD_Vertex> &verts = m_mesh.VertexSet();
MT_Vector3 vec1 =
verts[face.m_verts[1]].pos -
verts[face.m_verts[0]].pos;
MT_Vector3 vec2 =
verts[face.m_verts[2]].pos -
verts[face.m_verts[1]].pos;
vec1 = vec1.cross(vec2);
if (!vec1.fuzzyZero()) {
vec1.normalize();
return (vec1);
} else {
return (MT_Vector3(1.0,0,0));
}
}
const
MT_Vector3
LOD_ExternNormalEditor::
ComputeVertexNormal(
const LOD_VertexInd v
) const {
// average the face normals surrounding this
// vertex and normalize
// vector<LOD_Vertex> &verts = m_mesh.VertexSet(); /*unused*/
const vector<MT_Vector3> & face_normals = m_normals.Ref();
vector<LOD_FaceInd> vertex_faces;
vertex_faces.reserve(32);
m_mesh.VertexFaces(v,vertex_faces);
MT_Vector3 normal(0,0,0);
vector<LOD_FaceInd>::const_iterator face_it = vertex_faces.begin();
vector<LOD_FaceInd>::const_iterator face_end = vertex_faces.end();
for (; face_it != face_end; ++face_it) {
normal += face_normals[*face_it];
}
if (!normal.fuzzyZero()) {
normal.normalize();
return (normal);
} else {
return (MT_Vector3(1.0,0,0));
}
}

View File

@ -1,135 +0,0 @@
/*
* ***** BEGIN GPL LICENSE BLOCK *****
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software Foundation,
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*
* The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
* All rights reserved.
*
* The Original Code is: all of this file.
*
* Contributor(s): none yet.
*
* ***** END GPL LICENSE BLOCK *****
*/
/** \file decimation/intern/LOD_ExternNormalEditor.h
* \ingroup decimation
*/
#ifndef __LOD_EXTERNNORMALEDITOR_H__
#define __LOD_EXTERNNORMALEDITOR_H__
#include "MEM_NonCopyable.h"
#include "LOD_ManMesh2.h"
#include "MT_Vector3.h"
#include "../extern/LOD_decimation.h"
class LOD_ExternNormalEditor : public MEM_NonCopyable
{
public :
// Creation
///////////
static
LOD_ExternNormalEditor *
New(
LOD_Decimation_InfoPtr,
LOD_ManMesh2 &mesh
);
// Property editor interface
////////////////////////////
// Faces
////////
void
Remove(
std::vector<LOD_FaceInd> &sorted_faces
);
void
Add(
);
void
Update(
std::vector<LOD_FaceInd> &sorted_faces
);
const
std::vector<MT_Vector3> &
Normals(
) const {
return m_normals.Ref();
};
// vertex normals
/////////////////
void
RemoveVertexNormals(
std::vector<LOD_VertexInd> &sorted_verts
);
void
UpdateVertexNormals(
std::vector<LOD_VertexInd> &sorted_verts
);
// Editor specific methods
//////////////////////////
void
BuildNormals(
);
private :
MEM_SmartPtr<std::vector<MT_Vector3> > m_normals;
LOD_ManMesh2 &m_mesh;
LOD_Decimation_InfoPtr m_extern_info;
private :
LOD_ExternNormalEditor(
LOD_Decimation_InfoPtr extern_info,
LOD_ManMesh2 &mesh
);
const
MT_Vector3
ComputeNormal(
const LOD_TriFace &face
) const;
const
MT_Vector3
ComputeVertexNormal (
const LOD_VertexInd vi
) const;
};
#endif

View File

@ -1,291 +0,0 @@
/*
* ***** BEGIN GPL LICENSE BLOCK *****
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software Foundation,
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*
* The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
* All rights reserved.
*
* The Original Code is: all of this file.
*
* Contributor(s): none yet.
*
* ***** END GPL LICENSE BLOCK *****
*/
/** \file decimation/intern/LOD_FaceNormalEditor.cpp
* \ingroup decimation
*/
// implementation of LOD_FaceNormalEditor.h
///////////////////////////////////////
#include "LOD_FaceNormalEditor.h"
using namespace std;
LOD_FaceNormalEditor::
LOD_FaceNormalEditor(
LOD_ManMesh2 & mesh
) : m_mesh(mesh) {
};
LOD_FaceNormalEditor *
LOD_FaceNormalEditor::
New(
LOD_ManMesh2 &mesh
){
// build a set of normals of the same size
// as the number of polys in the mesh
MEM_SmartPtr<LOD_FaceNormalEditor> output(new LOD_FaceNormalEditor(mesh));
int face_num = mesh.FaceSet().size();
MEM_SmartPtr<vector<MT_Vector3> > normals(new vector<MT_Vector3>);
MEM_SmartPtr<vector<MT_Vector3> > vertex_normals(new vector<MT_Vector3>);
if (output == NULL ||
normals == NULL
) {
return NULL;
}
normals->reserve(face_num);
vertex_normals->reserve(mesh.VertexSet().size());
output->m_normals = normals.Release();
output->m_vertex_normals = vertex_normals.Release();
return output.Release();
};
// Property editor interface
////////////////////////////
void
LOD_FaceNormalEditor::
Remove(
std::vector<LOD_FaceInd> &sorted_faces
){
// assumes a collection of faces sorted in descending order .
vector<MT_Vector3> & normals = m_normals.Ref();
vector<LOD_FaceInd>::const_iterator it_start = sorted_faces.begin();
vector<LOD_FaceInd>::const_iterator it_end = sorted_faces.end();
for (; it_start != it_end; ++it_start) {
if (normals.size() > 0) {
MT_Vector3 temp = normals[*it_start];
normals[*it_start] = normals.back();
normals.back() = temp;
normals.pop_back();
}
// FIXME - through exception
}
}
void
LOD_FaceNormalEditor::
Add(
){
MT_Vector3 zero(0.0f,0.0f,0.0f);
m_normals->push_back(zero);
}
void
LOD_FaceNormalEditor::
Update(
std::vector<LOD_FaceInd> &sorted_faces
){
vector<MT_Vector3> & normals = m_normals.Ref();
vector<LOD_FaceInd>::const_iterator it_start = sorted_faces.begin();
vector<LOD_FaceInd>::const_iterator it_end = sorted_faces.end();
const vector<LOD_TriFace> &faces = m_mesh.FaceSet();
for (; it_start != it_end; ++it_start) {
normals[*it_start] = ComputeNormal(faces[*it_start]);
}
};
// vertex normals
/////////////////
void
LOD_FaceNormalEditor::
RemoveVertexNormals(
vector<LOD_VertexInd> &sorted_verts
){
vector<MT_Vector3> & vertex_normals = m_vertex_normals.Ref();
vector<LOD_VertexInd>::const_iterator it_start = sorted_verts.begin();
vector<LOD_VertexInd>::const_iterator it_end = sorted_verts.end();
for (; it_start != it_end; ++it_start) {
if (vertex_normals.size() > 0) {
MT_Vector3 temp = vertex_normals[*it_start];
vertex_normals[*it_start] = vertex_normals.back();
vertex_normals.back() = temp;
vertex_normals.pop_back();
}
// FIXME - through exception
}
};
void
LOD_FaceNormalEditor::
UpdateVertexNormals(
vector<LOD_VertexInd> &sorted_verts
){
vector<MT_Vector3> & vertex_normals = m_vertex_normals.Ref();
vector<LOD_VertexInd>::const_iterator it_start = sorted_verts.begin();
vector<LOD_VertexInd>::const_iterator it_end = sorted_verts.end();
for (; it_start != it_end; ++it_start) {
vertex_normals[*it_start] = ComputeVertexNormal(*it_start);
}
}
// Editor specific methods
//////////////////////////
void
LOD_FaceNormalEditor::
BuildNormals(
){
const vector<LOD_TriFace> &faces = m_mesh.FaceSet();
vector<MT_Vector3> & normals = m_normals.Ref();
int face_num = faces.size();
int cur_face = 0;
for (; cur_face < face_num; ++cur_face) {
MT_Vector3 new_normal = ComputeNormal(faces[cur_face]);
normals.push_back(new_normal);
}
// now build the vertex normals
vector<MT_Vector3> & vertex_normals = m_vertex_normals.Ref();
const vector<LOD_Vertex> &verts = m_mesh.VertexSet();
int vertex_num = verts.size();
int cur_vertex = 0;
for (; cur_vertex < vertex_num; ++cur_vertex) {
MT_Vector3 new_normal = ComputeVertexNormal(cur_vertex);
vertex_normals.push_back(new_normal);
}
}
const
MT_Vector3
LOD_FaceNormalEditor::
ComputeNormal(
const LOD_TriFace &face
) const {
const vector<LOD_Vertex> &verts = m_mesh.VertexSet();
MT_Vector3 vec1 =
verts[face.m_verts[1]].pos -
verts[face.m_verts[0]].pos;
MT_Vector3 vec2 =
verts[face.m_verts[2]].pos -
verts[face.m_verts[1]].pos;
vec1 = vec1.cross(vec2);
if (!vec1.fuzzyZero()) {
vec1.normalize();
return (vec1);
} else {
return (MT_Vector3(1.0,0,0));
}
}
const
MT_Vector3
LOD_FaceNormalEditor::
ComputeVertexNormal(
const LOD_VertexInd v
) const {
// average the face normals surrounding this
// vertex and normalize
const vector<MT_Vector3> & face_normals = m_normals.Ref();
vector<LOD_FaceInd> vertex_faces;
vertex_faces.reserve(32);
m_mesh.VertexFaces(v,vertex_faces);
MT_Vector3 normal(0,0,0);
vector<LOD_FaceInd>::const_iterator face_it = vertex_faces.begin();
vector<LOD_FaceInd>::const_iterator face_end = vertex_faces.end();
for (; face_it != face_end; ++face_it) {
normal += face_normals[*face_it];
}
if (!normal.fuzzyZero()) {
normal.normalize();
return (normal);
} else {
return (MT_Vector3(1.0,0,0));
}
}

View File

@ -1,144 +0,0 @@
/*
* ***** BEGIN GPL LICENSE BLOCK *****
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software Foundation,
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*
* The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
* All rights reserved.
*
* The Original Code is: all of this file.
*
* Contributor(s): none yet.
*
* ***** END GPL LICENSE BLOCK *****
*/
/** \file decimation/intern/LOD_FaceNormalEditor.h
* \ingroup decimation
*/
#ifndef __LOD_FACENORMALEDITOR_H__
#define __LOD_FACENORMALEDITOR_H__
#include "MEM_NonCopyable.h"
#include "LOD_ManMesh2.h"
#include "MT_Vector3.h"
class LOD_FaceNormalEditor : public MEM_NonCopyable
{
public :
// Creation
///////////
static
LOD_FaceNormalEditor *
New(
LOD_ManMesh2 &mesh
);
// Property editor interface
////////////////////////////
// Faces
////////
void
Remove(
std::vector<LOD_FaceInd> &sorted_faces
);
void
Add(
);
void
Update(
std::vector<LOD_FaceInd> &sorted_faces
);
// vertex normals
/////////////////
void
RemoveVertexNormals(
std::vector<LOD_VertexInd> &sorted_verts
);
void
UpdateVertexNormals(
std::vector<LOD_VertexInd> &sorted_verts
);
const
std::vector<MT_Vector3> &
Normals(
) const {
return m_normals.Ref();
};
const
std::vector<MT_Vector3> &
VertexNormals(
) const {
return m_vertex_normals.Ref();
};
// Editor specific methods
//////////////////////////
void
BuildNormals(
);
private :
MEM_SmartPtr<std::vector<MT_Vector3> > m_normals;
MEM_SmartPtr<std::vector<MT_Vector3> > m_vertex_normals;
LOD_ManMesh2 &m_mesh;
private :
LOD_FaceNormalEditor(LOD_ManMesh2 &mesh);
const
MT_Vector3
ComputeNormal(
const LOD_TriFace &face
) const;
const
MT_Vector3
ComputeVertexNormal (
const LOD_VertexInd vi
) const;
};
#endif

View File

@ -1,618 +0,0 @@
/*
* ***** BEGIN GPL LICENSE BLOCK *****
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software Foundation,
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*
* The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
* All rights reserved.
*
* The Original Code is: all of this file.
*
* Contributor(s): none yet.
*
* ***** END GPL LICENSE BLOCK *****
*/
/** \file decimation/intern/LOD_ManMesh2.cpp
* \ingroup decimation
*/
#include "LOD_ManMesh2.h"
#include "MT_assert.h"
#include <algorithm>
#include "LOD_MeshException.h"
#include "CTR_TaggedSetOps.h"
#include "CTR_UHeap.h"
#include "LOD_ExternBufferEditor.h"
using namespace std;
LOD_ManMesh2::
LOD_ManMesh2(
) :
m_bbox_min(0,0,0),
m_bbox_max(0,0,0)
{
}
LOD_ManMesh2 *
LOD_ManMesh2::
New(
){
MEM_SmartPtr<LOD_ManMesh2> output(new LOD_ManMesh2());
if (output == NULL) return NULL;
// build the vertex, edge and face sets.
MEM_SmartPtr<vector<LOD_Vertex> > verts(new vector<LOD_Vertex>);
MEM_SmartPtr<vector<LOD_TriFace> > faces(new vector<LOD_TriFace>);
MEM_SmartPtr<vector<LOD_Edge> > edges(new vector<LOD_Edge>);
if ((faces == NULL) || (edges == NULL) || (verts == NULL)) {
return NULL;
}
output->m_verts = verts.Release();
output->m_faces = faces.Release();
output->m_edges = edges.Release();
return output.Release();
}
// take ownership of the vertices.
bool
LOD_ManMesh2::
SetVertices(
MEM_SmartPtr<vector<LOD_Vertex> > verts
){
// take ownership of vertices
m_verts = verts;
// create a polygon and edge buffer of half the size
// and just use the automatic resizing feature of vector<>
// to worry about the dynamic array resizing
m_faces->clear();
m_edges->clear();
m_faces->reserve(m_verts->size()/2);
m_edges->reserve(m_verts->size()/2);
return true;
}
// add a triangle to the mesh
void
LOD_ManMesh2::
AddTriangle(
int verts[3]
) {
MT_assert(verts[0] < int(m_verts->size()));
MT_assert(verts[1] < int(m_verts->size()));
MT_assert(verts[2] < int(m_verts->size()));
LOD_TriFace face;
face.m_verts[0] = verts[0];
face.m_verts[1] = verts[1];
face.m_verts[2] = verts[2];
LOD_FaceInd face_index = m_faces->size();
m_faces->push_back(face);
// now work out if any of the directed edges or their
// companion edges exist already.
// We go through the edges associated with each of the given vertices
// the safest thing to do is iterate through each of the edge sets
// check against each of the 2 other triangle edges to see if they are there
vector<LOD_EdgeInd> new_edges;
new_edges.reserve(3);
InsertEdge(verts[0],verts[1],face_index,new_edges);
InsertEdge(verts[1],verts[2],face_index,new_edges);
InsertEdge(verts[2],verts[0],face_index,new_edges);
}
// Adds the index of any created edges to new_edges
bool
LOD_ManMesh2::
InsertEdge(
const LOD_VertexInd v1,
const LOD_VertexInd v2,
const LOD_FaceInd f,
vector<LOD_EdgeInd> &new_edges
){
MT_assert(!v1.IsEmpty());
MT_assert(!v2.IsEmpty());
MT_assert(!f.IsEmpty());
vector<LOD_Vertex> &verts = VertexSet();
vector<LOD_Edge> &edges = EdgeSet();
LOD_EdgeInd e;
e = FindEdge(v1,v2);
if (e.IsEmpty()) {
// This edge does not exist -- make a new one
LOD_Edge temp_e;
temp_e.m_verts[0] = v1;
temp_e.m_verts[1] = v2;
e = m_edges->size();
// set the face ptr for this half-edge
temp_e.m_faces[0] = f;
m_edges->push_back(temp_e);
// add the edge index to it's vertices
verts[v1].AddEdge(e);
verts[v2].AddEdge(e);
new_edges.push_back(e);
} else {
// edge already exists
// insure that there is no polygon already
// attached to the other side of this edge
// swap the empty face pointer in edge with f
LOD_Edge &edge = edges[e];
edge.SwapFace(LOD_FaceInd::Empty(),f);
}
return true;
}
void
LOD_ManMesh2::
ConnectTriangle(
LOD_FaceInd fi,
std::vector<LOD_EdgeInd> & new_edges
){
vector<LOD_TriFace> &faces = FaceSet();
MT_assert(!faces[fi].Degenerate());
LOD_TriFace & face = faces[fi];
InsertEdge(face.m_verts[0],face.m_verts[1],fi,new_edges);
InsertEdge(face.m_verts[1],face.m_verts[2],fi,new_edges);
InsertEdge(face.m_verts[2],face.m_verts[0],fi,new_edges);
};
// geometry access
//////////////////
vector<LOD_Vertex> &
LOD_ManMesh2::
VertexSet(
) const {
return m_verts.Ref();
}
vector<LOD_TriFace> &
LOD_ManMesh2::
FaceSet(
) const {
return m_faces.Ref();
}
vector<LOD_Edge> &
LOD_ManMesh2::
EdgeSet(
) const {
return m_edges.Ref();
};
LOD_ManMesh2::
~LOD_ManMesh2(
){
//auto ptr takes care of vertex arrays etc.
}
LOD_EdgeInd
LOD_ManMesh2::
FindEdge(
const LOD_VertexInd v1,
const LOD_VertexInd v2
) {
vector<LOD_Vertex> &verts = VertexSet();
vector<LOD_Edge> &edges = EdgeSet();
LOD_Edge e;
e.m_verts[0] = v1;
e.m_verts[1] = v2;
vector<LOD_EdgeInd> &v1_edges = verts[v1].m_edges;
vector<LOD_EdgeInd>::const_iterator v1_end = v1_edges.end();
vector<LOD_EdgeInd>::iterator v1_begin = v1_edges.begin();
for (; v1_begin != v1_end; ++v1_begin) {
if (edges[*v1_begin] == e) return *v1_begin;
}
return LOD_EdgeInd::Empty();
}
// face queries
///////////////
void
LOD_ManMesh2::
FaceVertices(
LOD_FaceInd fi,
vector<LOD_VertexInd> &output
){
const vector<LOD_TriFace> &faces = FaceSet();
const LOD_TriFace & f = faces[fi];
output.push_back(f.m_verts[0]);
output.push_back(f.m_verts[1]);
output.push_back(f.m_verts[2]);
}
void
LOD_ManMesh2::
FaceEdges(
LOD_FaceInd fi,
vector<LOD_EdgeInd> &output
){
const vector<LOD_TriFace> &faces = FaceSet();
vector<LOD_Edge> &edges = EdgeSet();
vector<LOD_Vertex> &verts = VertexSet();
const LOD_TriFace & f = faces[fi];
// intersect vertex edges
vector<LOD_EdgeInd> & v0_edges = verts[f.m_verts[0]].m_edges;
vector<LOD_EdgeInd> & v1_edges = verts[f.m_verts[1]].m_edges;
vector<LOD_EdgeInd> & v2_edges = verts[f.m_verts[2]].m_edges;
CTR_TaggedSetOps<LOD_EdgeInd,LOD_Edge>::IntersectPair(v0_edges,v1_edges,edges,output);
CTR_TaggedSetOps<LOD_EdgeInd,LOD_Edge>::IntersectPair(v1_edges,v2_edges,edges,output);
CTR_TaggedSetOps<LOD_EdgeInd,LOD_Edge>::IntersectPair(v2_edges,v0_edges,edges,output);
MT_assert(output.size() == 3);
if (output.size() != 3) {
LOD_MeshException e(LOD_MeshException::e_non_manifold);
throw(e);
}
}
// edge queries
///////////////
void
LOD_ManMesh2::
EdgeVertices(
LOD_EdgeInd ei,
vector<LOD_VertexInd> &output
){
const vector<LOD_Edge> &edges = EdgeSet();
const LOD_Edge & e = edges[ei];
output.push_back(e.m_verts[0]);
output.push_back(e.m_verts[1]);
}
void
LOD_ManMesh2::
EdgeFaces(
LOD_EdgeInd ei,
vector<LOD_FaceInd> &output
){
const vector<LOD_Edge> &edges = EdgeSet();
const LOD_Edge & e = edges[ei];
if (!e.m_faces[0].IsEmpty()) {
output.push_back(e.m_faces[0]);
}
if (!e.m_faces[1].IsEmpty()) {
output.push_back(e.m_faces[1]);
}
}
// vertex queries
/////////////////
void
LOD_ManMesh2::
VertexEdges(
LOD_VertexInd vi,
vector<LOD_EdgeInd> &output
){
// iterate through the edges of v and push them onto the
// output
vector<LOD_Vertex> &verts = VertexSet();
vector<LOD_EdgeInd> & v_edges = verts[vi].m_edges;
vector<LOD_EdgeInd>::iterator v_it = v_edges.begin();
for (; v_it != v_edges.end(); ++v_it) {
output.push_back(*v_it);
}
}
void
LOD_ManMesh2::
VertexFaces(
LOD_VertexInd vi,
vector<LOD_FaceInd> &output
){
const vector<LOD_Vertex> &verts = VertexSet();
vector<LOD_Edge> &edges = EdgeSet();
vector<LOD_TriFace> &faces = FaceSet();
const vector<LOD_EdgeInd> &v_edges = verts[vi].m_edges;
vector<LOD_EdgeInd>::const_iterator e_it = v_edges.begin();
for (; e_it != v_edges.end(); ++e_it) {
LOD_Edge &e = edges[*e_it];
if ((!e.m_faces[0].IsEmpty()) && (!faces[e.m_faces[0]].SelectTag())) {
output.push_back(e.m_faces[0]);
faces[e.m_faces[0]].SetSelectTag(true);
}
if ((!e.m_faces[1].IsEmpty()) && (!faces[e.m_faces[1]].SelectTag())) {
output.push_back(e.m_faces[1]);
faces[e.m_faces[1]].SetSelectTag(true);
}
}
vector<LOD_FaceInd>::iterator f_it = output.begin();
for (; f_it != output.end(); ++f_it) {
faces[*f_it].SetSelectTag(false);
}
};
void
LOD_ManMesh2::
SetBBox(
MT_Vector3 bbox_min,
MT_Vector3 bbox_max
){
m_bbox_min = bbox_min;
m_bbox_max = bbox_max;
};
void
LOD_ManMesh2::
SC_TriFace(
LOD_FaceInd f
){
LOD_TriFace face = (*m_faces)[f];
// check for unique vertices
if (
(face.m_verts[0] == face.m_verts[1]) ||
(face.m_verts[1] == face.m_verts[2]) ||
(face.m_verts[2] == face.m_verts[0])
) {
MT_assert(false);
}
}
void
LOD_ManMesh2::
SC_EdgeList(
LOD_VertexInd v
){
vector<LOD_Edge> &edges = EdgeSet();
vector<LOD_Vertex> &verts = VertexSet();
vector<LOD_EdgeInd>::iterator e_it = verts[v].m_edges.begin();
for (;e_it != verts[v].m_edges.end(); ++e_it) {
MT_assert( (edges[*e_it].m_verts[0] == v) || (edges[*e_it].m_verts[1] == v));
}
};
void
LOD_ManMesh2::
DeleteVertex(
LOD_ExternBufferEditor & extern_editor,
LOD_VertexInd v
){
vector<LOD_Edge> &edges = EdgeSet();
vector<LOD_Vertex> &verts = VertexSet();
vector<LOD_TriFace> &faces = FaceSet();
// need to update all the edge and polygons pointing to
// the last vertex in m_verts
if (verts.size() == 1) {
verts.clear();
return;
}
LOD_VertexInd last = LOD_VertexInd(size_t(verts.end() - verts.begin() - 1));
if (!(last == v)) {
// we asume that v is already disconnected
vector<LOD_FaceInd> v_faces;
vector<LOD_EdgeInd> v_edges;
v_faces.reserve(64);
v_edges.reserve(64);
VertexFaces(last,v_faces);
VertexEdges(last,v_edges);
// map the faces and edges to look at v
vector<LOD_FaceInd>::iterator face_it = v_faces.begin();
for(; face_it != v_faces.end(); ++face_it) {
faces[*face_it].SwapVertex(last,v);
}
vector<LOD_EdgeInd>::iterator edge_it = v_edges.begin();
for (; edge_it != v_edges.end(); ++edge_it) {
edges[*edge_it].SwapVertex(last,v);
}
// copy the last vertex onto v and pop off the back.
verts[v] = verts[last];
// tidy external buffer
extern_editor.CopyModifiedFaces(*this,v_faces);
}
verts.pop_back();
extern_editor.CopyBackVertex(v);
};
void
LOD_ManMesh2::
DeleteEdge(
LOD_EdgeInd e,
CTR_UHeap<LOD_Edge> * heap
){
vector<LOD_Edge> &edges = EdgeSet();
vector<LOD_Vertex> &verts = VertexSet();
if (edges.size() == 1) {
edges.clear();
return;
}
LOD_EdgeInd last = LOD_EdgeInd(size_t(edges.end() - edges.begin() - 1));
if (!(last == e)) {
vector<LOD_EdgeInd> e_verts;
e_verts.reserve(2);
EdgeVertices(last,e_verts);
// something is wrong if there arent two!
verts[e_verts[0]].SwapEdge(last,e);
verts[e_verts[1]].SwapEdge(last,e);
// edges[e] should already have been removed from the heap
MT_assert(edges[e].HeapPos() == -1);
edges[e] = edges[last];
// also have to swap there heap positions.!!!!!
heap->HeapVector()[edges[e].HeapPos()] = e;
}
edges.pop_back();
};
void
LOD_ManMesh2::
DeleteFace(
LOD_ExternBufferEditor & extern_editor,
LOD_FaceInd f
){
vector<LOD_Edge> &edges = EdgeSet();
vector<LOD_TriFace> &faces = FaceSet();
if (faces.size() == 1) {
faces.clear();
return;
}
LOD_FaceInd last = LOD_FaceInd(size_t (faces.end() - faces.begin() - 1));
if (!(last == f)) {
// we have to update the edges which point to the last
// face
vector<LOD_EdgeInd> f_edges;
f_edges.reserve(3);
FaceEdges(last,f_edges);
vector<LOD_EdgeInd>::iterator edge_it = f_edges.begin();
vector<LOD_EdgeInd>::const_iterator edge_end = f_edges.end();
for (; edge_it != edge_end; ++edge_it) {
edges[*edge_it].SwapFace(last,f);
}
faces[f] = faces[last];
}
faces.pop_back();
// tidy external buffers
extern_editor.CopyBackFace(f);
};

View File

@ -1,265 +0,0 @@
/*
* ***** BEGIN GPL LICENSE BLOCK *****
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software Foundation,
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*
* The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
* All rights reserved.
*
* The Original Code is: all of this file.
*
* Contributor(s): none yet.
*
* ***** END GPL LICENSE BLOCK *****
*/
/** \file decimation/intern/LOD_ManMesh2.h
* \ingroup decimation
*/
#ifndef __LOD_MANMESH2_H__
#define __LOD_MANMESH2_H__
#include "LOD_MeshPrimitives.h"
#include "MEM_SmartPtr.h"
#include <vector>
template <class HeapType> class CTR_UHeap;
class LOD_ExternBufferEditor;
class LOD_ManMesh2 // Manifold 2 dimensional mesh
{
public:
static
LOD_ManMesh2 *
New(
);
// take ownership of the vertices.
bool
SetVertices(
MEM_SmartPtr<std::vector<LOD_Vertex> > verts
);
// Add a triangle to the mesh
void
AddTriangle(
int verts[3]
);
void
ConnectTriangle(
LOD_FaceInd fi,
std::vector<LOD_EdgeInd> & new_edges
);
// geometry access
//////////////////
std::vector<LOD_Vertex> &
VertexSet(
) const;
std::vector<LOD_TriFace> &
FaceSet(
) const;
std::vector<LOD_Edge> &
EdgeSet(
) const;
~LOD_ManMesh2(
);
// local geometry queries
/////////////////////////
// face queries
///////////////
void
FaceVertices(
LOD_FaceInd f,
std::vector<LOD_VertexInd> &output
);
void
FaceEdges(
LOD_FaceInd f,
std::vector<LOD_EdgeInd> &output
);
// edge queries
///////////////
void
EdgeVertices(
LOD_EdgeInd e,
std::vector<LOD_VertexInd> &output
);
void
EdgeFaces(
LOD_EdgeInd e,
std::vector<LOD_FaceInd> &output
);
// vertex queries
/////////////////
void
VertexEdges(
LOD_VertexInd v,
std::vector<LOD_EdgeInd> &output
);
void
VertexFaces(
LOD_VertexInd v,
std::vector<LOD_FaceInd> &output
);
void
SetBBox(
MT_Vector3 bbox_min,
MT_Vector3 bbox_max
);
MT_Vector3
BBoxMin(
) const {
return m_bbox_min;
};
MT_Vector3
BBoxMax(
) const {
return m_bbox_max;
};
// Remove a primitive from the mesh
///////////////////////////////////
// These methods assume you have correctly
// tidied up the index pointers in other primitives,
// so that nothing refers to this object any more
// These methods exchange the primitive with the
// last primitive in the vector. It modifies everything
// pointing to the last primitive correctly.
// FIXME refactor extern editor out of primitive deletion
// insead return a vector of primitives that need to be
// modified and do this externally
void
DeleteVertex(
LOD_ExternBufferEditor & extern_editor,
LOD_VertexInd v
);
void
DeleteEdge(
LOD_EdgeInd e,
CTR_UHeap<LOD_Edge> *heap
);
void
DeleteFace(
LOD_ExternBufferEditor & extern_editor,
LOD_FaceInd f
);
// Sanity Check routines
////////////////////////
// Make sure the edge sets and the vertex sets are
// consistent
void
SC_TriFace(
LOD_FaceInd f
);
// basic sanity checking of an edge list bails out if there are more than 1024
// edges
void
SC_EdgeList(
LOD_EdgeInd e
);
// Check to see that the edges of v1 and v2 are unique.
bool
SC_UniqueEdge(
LOD_EdgeInd e
);
private :
// Returns the edge index of the edge from v1 to v2.
// Does this by searching the edge sets of v1 - but not v2.
// If you are paranoid you should check both and make sure the
// indices are the same. If the edge doe not exist edgeInd is empty.
LOD_EdgeInd
FindEdge(
const LOD_VertexInd v1,
const LOD_VertexInd v2
);
// Insert an edge into the mesh
// Tie up the ptrs and create space for the edge
// returns manifold errors - need to sort out memory edges
bool
InsertEdge(
const LOD_VertexInd v1,
const LOD_VertexInd v2,
const LOD_FaceInd f,
std::vector<LOD_EdgeInd> &new_edges
);
private :
LOD_ManMesh2(
);
MEM_SmartPtr< std::vector<LOD_Vertex> > m_verts;
MEM_SmartPtr< std::vector<LOD_TriFace> > m_faces;
MEM_SmartPtr< std::vector<LOD_Edge> > m_edges;
// not sure of these descrtiptions of the mesh should
// reside in this class coz may lead to very bloated interface.
MT_Vector3 m_bbox_min;
MT_Vector3 m_bbox_max;
};
#endif

View File

@ -1,133 +0,0 @@
/*
* ***** BEGIN GPL LICENSE BLOCK *****
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software Foundation,
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*
* The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
* All rights reserved.
*
* The Original Code is: all of this file.
*
* Contributor(s): none yet.
*
* ***** END GPL LICENSE BLOCK *****
*/
/** \file decimation/intern/LOD_MeshBounds.h
* \ingroup decimation
*/
#ifndef __LOD_MESHBOUNDS_H__
#define __LOD_MESHBOUNDS_H__
#include "MEM_SmartPtr.h"
#include "LOD_MeshPrimitives.h"
#include "LOD_ManMesh2.h"
#include "MT_assert.h"
// simple class to compute the mesh bounds of a manifold mesh,
class LOD_MeshBounds {
public :
static
LOD_MeshBounds *
New(
){
MEM_SmartPtr<LOD_MeshBounds> output(new LOD_MeshBounds());
return output.Release();
}
void
ComputeBounds(
const LOD_ManMesh2 * mesh
){
MT_assert(mesh!=NULL);
MT_assert(mesh->VertexSet().size() > 0);
const std::vector<LOD_Vertex> &verts = mesh->VertexSet();
m_min = verts[0].pos;
m_max = verts[0].pos;
// iterate through the verts
int t;
const int size = verts.size();
for (t=1; t< size ; ++t) {
UpdateBounds(verts[t].pos,m_min,m_max);
}
}
MT_Vector3
Min(
) const {
return m_min;
}
MT_Vector3
Max(
) const {
return m_max;
}
private :
void
UpdateBounds(
MT_Vector3 vertex,
MT_Vector3& min,
MT_Vector3& max
) {
if (vertex.x() < min.x()) {
min.x() = vertex.x();
} else
if (vertex.x() > max.x()) {
max.x()= vertex.x();
}
if (vertex.y() < min.y()) {
min.y() = vertex.y();
} else
if (vertex.y() > max.y()) {
max.y()= vertex.y();
}
if (vertex.z() < min.z()) {
min.z() = vertex.z();
} else
if (vertex.z() > max.z()) {
max.z()= vertex.z();
}
}
LOD_MeshBounds(
) :
m_min(0,0,0),
m_max(0,0,0)
{
};
MT_Vector3 m_min;
MT_Vector3 m_max;
};
#endif

View File

@ -1,55 +0,0 @@
/*
* ***** BEGIN GPL LICENSE BLOCK *****
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software Foundation,
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*
* The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
* All rights reserved.
*
* The Original Code is: all of this file.
*
* Contributor(s): none yet.
*
* ***** END GPL LICENSE BLOCK *****
*/
/** \file decimation/intern/LOD_MeshException.h
* \ingroup decimation
*/
#ifndef __LOD_MESHEXCEPTION_H__
#define __LOD_MESHEXCEPTION_H__
class LOD_MeshException {
public :
// stick in more error types as you think of them
enum ExceptionType{
e_non_manifold,
e_search_error
} m_e_type;
LOD_MeshException (
ExceptionType type
) : m_e_type (type)
{
}
};
#endif

View File

@ -1,404 +0,0 @@
/*
* ***** BEGIN GPL LICENSE BLOCK *****
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software Foundation,
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*
* The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
* All rights reserved.
*
* The Original Code is: all of this file.
*
* Contributor(s): none yet.
*
* ***** END GPL LICENSE BLOCK *****
*/
/** \file decimation/intern/LOD_MeshPrimitives.cpp
* \ingroup decimation
*/
#include "LOD_MeshPrimitives.h"
#include "MT_assert.h"
#include "LOD_MeshException.h"
#include <algorithm>
using namespace std;
// Vertex Methods
/////////////////
LOD_Vertex::
LOD_Vertex(
) :
pos (MT_Vector3()),
m_select_tag(false)
{
};
bool
LOD_Vertex::
RemoveEdge(
LOD_EdgeInd e
){
vector<LOD_EdgeInd>::iterator result = find(m_edges.begin(),m_edges.end(),e);
if (result == m_edges.end()) {
return false;
}
std::swap(*result, m_edges.back());
m_edges.pop_back();
return true;
};
void
LOD_Vertex::
AddEdge(
LOD_EdgeInd e
){
m_edges.push_back(e);
};
void
LOD_Vertex::
SwapEdge(
LOD_EdgeInd e_old,
LOD_EdgeInd e_new
){
vector<LOD_EdgeInd>::iterator result =
find(m_edges.begin(),m_edges.end(),e_old);
if (result == m_edges.end()) {
MT_assert(false);
LOD_MeshException e(LOD_MeshException::e_search_error);
throw(e);
}
*result = e_new;
};
bool
LOD_Vertex::
SelectTag(
) const {
return m_select_tag;
};
void
LOD_Vertex::
SetSelectTag(
bool tag
){
m_select_tag = tag;
};
bool
LOD_Vertex::
Degenerate(
){
return m_edges.empty();
}
void
LOD_Vertex::
CopyPosition(
float *float_ptr
){
pos.getValue(float_ptr);
}
// Edge Methods
///////////////
LOD_Edge::
LOD_Edge (
) {
m_verts[0] = m_verts[1] = LOD_VertexInd::Empty();
m_faces[0] = m_faces[1] = LOD_FaceInd::Empty();
}
bool
LOD_Edge::
operator == (
LOD_Edge & rhs
) {
// edges are the same if their vertex indices are the
// same!!! Other properties are not checked
int matches = 0;
if (this->m_verts[0] == rhs.m_verts[0]) {
++matches;
}
if (this->m_verts[1] == rhs.m_verts[0]) {
++matches;
}
if (this->m_verts[0] == rhs.m_verts[1]) {
++matches;
}
if (this->m_verts[1] == rhs.m_verts[1]) {
++matches;
}
if (matches >= 2) {
return true;
}
return false;
}
// Elementary helper methods
////////////////////////////
LOD_FaceInd
LOD_Edge::
OpFace(
LOD_FaceInd f
) const {
if (f == m_faces[0]) {
return m_faces[1];
} else
if (f == m_faces[1]) {
return m_faces[0];
} else {
MT_assert(false);
LOD_MeshException e(LOD_MeshException::e_search_error);
throw(e);
return LOD_FaceInd::Empty();
}
}
void
LOD_Edge::
SwapFace(
LOD_FaceInd old_f,
LOD_FaceInd new_f
) {
if (old_f == m_faces[0]) {
m_faces[0] = new_f;
} else
if (old_f == m_faces[1]) {
m_faces[1] = new_f;
} else {
LOD_MeshException e(LOD_MeshException::e_search_error);
throw(e);
}
}
// return the half edge face - the half edge is defined
// by the {vertex,edge} tuple.
LOD_FaceInd
LOD_Edge::
HalfEdgeFace(
LOD_VertexInd vi
){
if (vi == m_verts[0]) return m_faces[0];
if (vi == m_verts[1]) return m_faces[1];
MT_assert(false);
LOD_MeshException e(LOD_MeshException::e_search_error);
throw(e);
return LOD_FaceInd::Empty();
}
LOD_VertexInd
LOD_Edge::
OpVertex(
LOD_VertexInd vi
) {
if (vi == m_verts[0]) return m_verts[1];
if (vi == m_verts[1]) return m_verts[0];
MT_assert(false);
LOD_MeshException e(LOD_MeshException::e_search_error);
throw(e);
return LOD_VertexInd::Empty();
}
// replace the vertex v_old with vertex v_new
// error if v_old is not one of the original vertices
void
LOD_Edge::
SwapVertex(
LOD_VertexInd v_old,
LOD_VertexInd v_new
) {
if (v_old == m_verts[0]) {
m_verts[0] = v_new;
} else
if (v_old == m_verts[1]) {
m_verts[1] = v_new;
} else {
MT_assert(false);
LOD_MeshException e(LOD_MeshException::e_search_error);
throw(e);
}
if(m_verts[0] == m_verts[1]) {
MT_assert(false);
LOD_MeshException e(LOD_MeshException::e_non_manifold);
throw(e);
}
}
bool
LOD_Edge::
SelectTag(
) const {
return bool(m_verts[1].Tag() & 0x1);
};
void
LOD_Edge::
SetSelectTag(
bool tag
) {
m_verts[1].SetTag(int(tag));
};
int
LOD_Edge::
OpenTag(
) const {
return m_faces[0].Tag();
}
void
LOD_Edge::
SetOpenTag(
int tag
) {
m_faces[0].SetTag(tag);
}
bool
LOD_Edge::
Degenerate(
) const {
return (
(m_faces[0].IsEmpty() && m_faces[1].IsEmpty()) ||
(m_verts[0] == m_verts[1])
);
};
// TriFace Methods
//////////////////
LOD_TriFace::
LOD_TriFace(
) {
m_verts[0] = m_verts[1] = m_verts[2] = LOD_VertexInd::Empty();
}
// Elementary helper methods
////////////////////////////
void
LOD_TriFace::
SwapVertex(
LOD_VertexInd old_v,
LOD_VertexInd new_v
) {
// could save branching here...
if (m_verts[0] == old_v) {
m_verts[0] = new_v;
} else
if (m_verts[1] == old_v) {
m_verts[1] = new_v;
} else
if (m_verts[2] == old_v) {
m_verts[2] = new_v;
} else {
MT_assert(false);
LOD_MeshException excep(LOD_MeshException::e_search_error);
throw(excep);
}
}
bool
LOD_TriFace::
SelectTag(
) const {
return bool(m_verts[1].Tag() & 0x1);
};
void
LOD_TriFace::
SetSelectTag(
bool tag
) {
m_verts[1].SetTag(int(tag));
};
int
LOD_TriFace::
OpenTag(
) {
return m_verts[2].Tag();
}
void
LOD_TriFace::
SetOpenTag(
int tag
) {
m_verts[2].SetTag(tag);
}
bool
LOD_TriFace::
Degenerate(
) {
return (
(m_verts[0] == m_verts[1]) ||
(m_verts[1] == m_verts[2]) ||
(m_verts[2] == m_verts[0])
);
}
void
LOD_TriFace::
CopyVerts(
int * index_ptr
){
index_ptr[0] = m_verts[0];
index_ptr[1] = m_verts[1];
index_ptr[2] = m_verts[2];
};

View File

@ -1,221 +0,0 @@
/*
* ***** BEGIN GPL LICENSE BLOCK *****
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software Foundation,
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*
* The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
* All rights reserved.
*
* The Original Code is: all of this file.
*
* Contributor(s): none yet.
*
* ***** END GPL LICENSE BLOCK *****
*/
/** \file decimation/intern/LOD_MeshPrimitives.h
* \ingroup decimation
*/
#ifndef __LOD_MESHPRIMITIVES_H__
#define __LOD_MESHPRIMITIVES_H__
#include "MT_Vector3.h"
#include "CTR_TaggedIndex.h"
#include "CTR_UHeap.h"
#include <vector>
typedef CTR_TaggedIndex<24,0x00ffffff> LOD_VertexInd;
typedef CTR_TaggedIndex<24,0x00ffffff> LOD_EdgeInd;
typedef CTR_TaggedIndex<24,0x00ffffff> LOD_FaceInd;
typedef CTR_TaggedIndex<24,0x00ffffff> LOD_HeapInd;
class LOD_Vertex {
public :
MT_Vector3 pos;
std::vector<LOD_EdgeInd> m_edges;
bool m_select_tag;
LOD_Vertex(
);
bool
RemoveEdge(
LOD_EdgeInd e
);
void
AddEdge(
LOD_EdgeInd e
);
void
SwapEdge(
LOD_EdgeInd e_old,
LOD_EdgeInd e_new
);
bool
SelectTag(
) const;
void
SetSelectTag(
bool tag
);
bool
Degenerate(
);
void
CopyPosition(
float *float_ptr
);
private :
};
class LOD_Edge : public CTR_UHeapable {
public :
LOD_VertexInd m_verts[2];
LOD_FaceInd m_faces[2];
LOD_Edge (
);
bool operator == (
LOD_Edge & rhs
);
// Elementary helper methods
////////////////////////////
LOD_FaceInd
OpFace(
LOD_FaceInd f
) const;
void
SwapFace(
LOD_FaceInd old_f,
LOD_FaceInd new_f
);
// return the half edge face - the half edge is defined
// by the {vertex,edge} tuple.
LOD_FaceInd
HalfEdgeFace(
LOD_VertexInd vi
);
LOD_VertexInd
OpVertex(
LOD_VertexInd vi
);
// replace the vertex v_old with vertex v_new
// error if v_old is not one of the original vertices
void
SwapVertex(
LOD_VertexInd v_old,
LOD_VertexInd v_new
);
bool
SelectTag(
) const;
void
SetSelectTag(
bool tag
);
int
OpenTag(
) const;
void
SetOpenTag(
int tag
);
bool
Degenerate(
) const;
bool
BoundaryEdge(
) const {
return (m_faces[0].IsEmpty() || m_faces[1].IsEmpty());
};
};
class LOD_TriFace {
public:
LOD_VertexInd m_verts[3];
LOD_TriFace(
);
// Elementary helper methods
////////////////////////////
void
SwapVertex(
LOD_VertexInd old_v,
LOD_VertexInd new_v
);
bool
SelectTag(
) const;
void
SetSelectTag(
bool tag
);
int
OpenTag(
);
void
SetOpenTag(
int tag
);
bool
Degenerate(
);
void
CopyVerts(
int * index_ptr
);
};
#endif

View File

@ -1,327 +0,0 @@
/*
* ***** BEGIN GPL LICENSE BLOCK *****
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software Foundation,
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*
* The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
* All rights reserved.
*
* The Original Code is: all of this file.
*
* Contributor(s): none yet.
*
* ***** END GPL LICENSE BLOCK *****
*/
/** \file decimation/intern/LOD_QSDecimator.cpp
* \ingroup decimation
*/
#include "LOD_QSDecimator.h"
#include "LOD_ExternBufferEditor.h"
using namespace std;
LOD_QSDecimator *
LOD_QSDecimator::
New(
LOD_ManMesh2 &mesh,
LOD_ExternNormalEditor &face_editor,
LOD_ExternBufferEditor &extern_editor
){
MEM_SmartPtr<LOD_QSDecimator> output
= new LOD_QSDecimator(mesh,face_editor,extern_editor);
MEM_SmartPtr<LOD_EdgeCollapser > collapser(LOD_EdgeCollapser::New());
MEM_SmartPtr<LOD_QuadricEditor> q_editor(LOD_QuadricEditor::New(mesh));
if (
output == NULL ||
collapser == NULL ||
q_editor == NULL
) {
return NULL;
}
output->m_collapser = collapser.Release();
output->m_quadric_editor = q_editor.Release();
return output.Release();
}
bool
LOD_QSDecimator::
Arm(
){
MT_assert(!m_is_armed);
bool heap_result = BuildHeap();
if (!heap_result) {
return false;
}
m_is_armed = true;
return true;
}
bool
LOD_QSDecimator::
Step(
){
return CollapseEdge();
}
LOD_QSDecimator::
LOD_QSDecimator(
LOD_ManMesh2 &mesh,
LOD_ExternNormalEditor &face_editor,
LOD_ExternBufferEditor &extern_editor
) :
m_is_armed (false),
m_mesh(mesh),
m_face_editor(face_editor),
m_extern_editor(extern_editor)
{
m_deg_edges.reserve(32);
m_deg_faces.reserve(32);
m_deg_vertices.reserve(32);
m_update_faces.reserve(32);
m_new_edges.reserve(32);
m_update_vertices.reserve(32);
};
bool
LOD_QSDecimator::
CollapseEdge(
){
// find an edge to collapse
// FIXME force an edge collapse
// or return false
std::vector<LOD_Edge> & edges = m_mesh.EdgeSet();
std::vector<LOD_Vertex> & verts = m_mesh.VertexSet();
std::vector<LOD_Quadric> & quadrics = m_quadric_editor->Quadrics();
int size = edges.size();
if (size == 0) return false;
const int heap_top = m_heap->Top();
if (heap_top == -1 || edges[heap_top].HeapKey() <= -MT_INFINITY) {
return false;
}
// compute the target position
MT_Vector3 new_vertex = m_quadric_editor->TargetVertex(edges[heap_top]);
LOD_Quadric & q0 = quadrics[edges[heap_top].m_verts[0]];
LOD_Quadric & q1 = quadrics[edges[heap_top].m_verts[1]];
LOD_Vertex &v0 = verts[edges[heap_top].m_verts[0]];
LOD_Vertex &v1 = verts[edges[heap_top].m_verts[1]];
LOD_Quadric sum = q0;
sum += q1;
if (m_collapser->CollapseEdge(
heap_top,
m_mesh,
m_deg_edges,
m_deg_faces,
m_deg_vertices,
m_new_edges,
m_update_faces,
m_update_vertices
)) {
// assign new vertex position
v0.pos = new_vertex;
v1.pos = new_vertex;
// sum the quadrics of v0 and v1
q0 = sum;
q1 = sum;
// ok update the primitive properties
m_face_editor.Update(m_update_faces);
m_face_editor.UpdateVertexNormals(m_update_vertices);
// update the external vertex buffer
m_extern_editor.CopyModifiedVerts(m_mesh,m_update_vertices);
// update the external face buffer
m_extern_editor.CopyModifiedFaces(m_mesh,m_update_faces);
// update the edge heap
UpdateHeap(m_deg_edges,m_new_edges);
m_quadric_editor->Remove(m_deg_vertices);
m_face_editor.Remove(m_deg_faces);
m_face_editor.RemoveVertexNormals(m_deg_vertices);
// delete the primitives
DeletePrimitives(m_deg_edges,m_deg_faces,m_deg_vertices);
} else {
// the edge could not be collapsed at the moment - so
// we adjust it's priority and add it back to the heap.
m_heap->Remove(&edges[0],0);
edges[heap_top].HeapKey() = - MT_INFINITY;
m_heap->Insert(&edges[0],heap_top);
}
//clear all the temporary buffers
m_deg_faces.clear();
m_deg_edges.clear();
m_deg_vertices.clear();
m_update_faces.clear();
m_update_vertices.clear();
m_new_edges.clear();
return true;
}
void
LOD_QSDecimator::
DeletePrimitives(
const vector<LOD_EdgeInd> & degenerate_edges,
const vector<LOD_FaceInd> & degenerate_faces,
const vector<LOD_VertexInd> & degenerate_vertices
) {
// assumes that the 3 vectors are sorted in descending order.
// Delete Degnerate primitives
//////////////////////////////
// delete the old edges - we have to be very careful here
// mesh.delete() swaps edges to be deleted with the last edge in
// the edge buffer. However the next edge to be deleted may have
// been the last edge in the buffer!
// One way to solve this is to sort degenerate_edges in descending order.
// And then delete them in that order.
// it is also vital that degenerate_edges contains no duplicates
vector<LOD_EdgeInd>::const_iterator edge_it = degenerate_edges.begin();
vector<LOD_EdgeInd>::const_iterator edge_end = degenerate_edges.end();
for (; edge_it != edge_end; ++edge_it) {
m_mesh.DeleteEdge(*edge_it,m_heap);
}
vector<LOD_FaceInd>::const_iterator face_it = degenerate_faces.begin();
vector<LOD_FaceInd>::const_iterator face_end = degenerate_faces.end();
for (;face_it != face_end; ++face_it) {
m_mesh.DeleteFace(m_extern_editor,*face_it);
}
vector<LOD_VertexInd>::const_iterator vertex_it = degenerate_vertices.begin();
vector<LOD_VertexInd>::const_iterator vertex_end = degenerate_vertices.end();
for (;vertex_it != vertex_end; ++vertex_it) {
m_mesh.DeleteVertex(m_extern_editor,*vertex_it);
}
}
bool
LOD_QSDecimator::
BuildHeap(
){
// build the quadrics
if (m_quadric_editor->BuildQuadrics(m_face_editor,true) == false) return false;
m_heap = CTR_UHeap<LOD_Edge>::New();
// load in edge pointers to the heap
std::vector<LOD_Edge> & edge_set= m_mesh.EdgeSet();
// UNUSED
// std::vector<LOD_Edge>::const_iterator edge_end = edge_set.end();
// std::vector<LOD_Edge>::iterator edge_start = edge_set.begin();
std::vector<int> & heap_vector = m_heap->HeapVector();
for (unsigned int i = 0; i < edge_set.size(); ++i) {
edge_set[i].HeapPos() = i;
heap_vector.push_back(i);
}
m_heap->MakeHeap(&edge_set[0]);
return true;
}
void
LOD_QSDecimator::
UpdateHeap(
std::vector<LOD_EdgeInd> &deg_edges,
std::vector<LOD_EdgeInd> &new_edges
){
// first of all compute values for the new edges
// and bung them on the heap.
std::vector<LOD_Edge> & edge_set= m_mesh.EdgeSet();
std::vector<LOD_EdgeInd>::const_iterator edge_it = new_edges.begin();
std::vector<LOD_EdgeInd>::const_iterator end_it = new_edges.end();
// insert all the new edges
///////////////////////////
// compute edge costs ffor the new edges
m_quadric_editor->ComputeEdgeCosts(new_edges);
// inser the new elements into the heap
for (; edge_it != end_it; ++edge_it) {
m_heap->Insert(&edge_set[0],*edge_it);
}
// remove all the old values from the heap
edge_it = deg_edges.begin();
end_it = deg_edges.end();
for (; edge_it != end_it; ++edge_it) {
LOD_Edge &e = edge_set[*edge_it];
m_heap->Remove(&edge_set[0],e.HeapPos());
e.HeapPos() = -1;
}
}

View File

@ -1,129 +0,0 @@
/*
* ***** BEGIN GPL LICENSE BLOCK *****
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software Foundation,
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*
* The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
* All rights reserved.
*
* The Original Code is: all of this file.
*
* Contributor(s): none yet.
*
* ***** END GPL LICENSE BLOCK *****
*/
/** \file decimation/intern/LOD_QSDecimator.h
* \ingroup decimation
*/
#ifndef __LOD_QSDECIMATOR_H__
#define __LOD_QSDECIMATOR_H__
#include "MEM_NonCopyable.h"
#include "LOD_ManMesh2.h"
#include "LOD_ExternNormalEditor.h"
#include "LOD_EdgeCollapser.h"
#include "LOD_QuadricEditor.h"
class LOD_ExternBufferEditor;
class LOD_QSDecimator : public MEM_NonCopyable {
public :
static
LOD_QSDecimator *
New(
LOD_ManMesh2 &mesh,
LOD_ExternNormalEditor &face_editor,
LOD_ExternBufferEditor &extern_editor
);
bool
Arm(
);
bool
Step(
);
private :
LOD_QSDecimator(
LOD_ManMesh2 &mesh,
LOD_ExternNormalEditor &face_editor,
LOD_ExternBufferEditor &extern_editor
);
bool
CollapseEdge(
);
bool
BuildHeap(
);
void
UpdateHeap(
std::vector<LOD_EdgeInd> &deg_edges,
std::vector<LOD_EdgeInd> &new_edges
);
void
DeletePrimitives(
const std::vector<LOD_EdgeInd> & degenerate_edges,
const std::vector<LOD_FaceInd> & degenerate_faces,
const std::vector<LOD_VertexInd> & degenerate_vertices
);
private :
// owned by this class
//////////////////////
MEM_SmartPtr<LOD_EdgeCollapser> m_collapser;
MEM_SmartPtr<CTR_UHeap<LOD_Edge> > m_heap;
MEM_SmartPtr<LOD_QuadricEditor> m_quadric_editor;
bool m_is_armed;
// arguments to New(...)
////////////////////////
LOD_ManMesh2 & m_mesh;
LOD_ExternNormalEditor &m_face_editor;
LOD_ExternBufferEditor & m_extern_editor;
// temporary buffers
////////////////////
std::vector<LOD_FaceInd> m_deg_faces;
std::vector<LOD_EdgeInd> m_deg_edges;
std::vector<LOD_VertexInd> m_deg_vertices;
std::vector<LOD_FaceInd> m_update_faces;
std::vector<LOD_EdgeInd> m_new_edges;
std::vector<LOD_VertexInd> m_update_vertices;
};
#endif

View File

@ -1,167 +0,0 @@
/*
* ***** BEGIN GPL LICENSE BLOCK *****
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software Foundation,
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*
* The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
* All rights reserved.
*
* The Original Code is: all of this file.
*
* Contributor(s): none yet.
*
* ***** END GPL LICENSE BLOCK *****
*/
/** \file decimation/intern/LOD_Quadric.h
* \ingroup decimation
*/
#ifndef __LOD_QUADRIC_H__
#define __LOD_QUADRIC_H__
#include "MT_Vector3.h"
#include "MT_Matrix3x3.h"
class LOD_Quadric {
private:
MT_Scalar a2, ab, ac, ad;
MT_Scalar b2, bc, bd;
MT_Scalar c2, cd;
MT_Scalar d2;
//void init(MT_Scalar a, MT_Scalar b, MT_Scalar c, MT_Scalar d);
public:
LOD_Quadric(
) {
Clear();
};
LOD_Quadric(
const MT_Vector3 & vec,
const MT_Scalar & offset
) {
a2 = vec[0] *vec[0];
b2 = vec[1] *vec[1];
c2 = vec[2] *vec[2];
ab = vec[0]*vec[1];
ac = vec[0]*vec[2];
bc = vec[1]*vec[2];
MT_Vector3 temp = vec*offset;
ad = temp[0];
bd = temp[1];
cd = temp[2];
d2 = offset*offset;
};
MT_Matrix3x3
Tensor(
) const {
// return a symmetric matrix
return MT_Matrix3x3(
a2,ab,ac,
ab,b2,bc,
ac,bc,c2
);
};
MT_Vector3
Vector(
) const {
return MT_Vector3(ad, bd, cd);
};
void
Clear(
MT_Scalar val=0.0
) {
a2=ab=ac=ad=b2=bc=bd=c2=cd=d2=val;
};
LOD_Quadric &
operator=(
const LOD_Quadric& Q
) {
a2 = Q.a2; ab = Q.ab; ac = Q.ac; ad = Q.ad;
b2 = Q.b2; bc = Q.bc; bd = Q.bd;
c2 = Q.c2; cd = Q.cd;
d2 = Q.d2;
return *this;
};
LOD_Quadric&
operator+=(
const LOD_Quadric& Q
) {
a2 += Q.a2; ab += Q.ab; ac += Q.ac; ad += Q.ad;
b2 += Q.b2; bc += Q.bc; bd += Q.bd;
c2 += Q.c2; cd += Q.cd;
d2 += Q.d2;
return *this;
};
LOD_Quadric&
operator*=(
const MT_Scalar & s
) {
a2 *= s; ab *= s; ac *= s; ad *= s;
b2 *= s; bc *= s; bd *= s;
c2 *= s; cd *= s;
d2 *= s;
return *this;
};
MT_Scalar
Evaluate(
const MT_Vector3 &v
) const {
// compute the LOD_Quadric error
return v[0]*v[0]*a2 + 2*v[0]*v[1]*ab + 2*v[0]*v[2]*ac + 2*v[0]*ad
+v[1]*v[1]*b2 + 2*v[1]*v[2]*bc + 2*v[1]*bd
+v[2]*v[2]*c2 + 2*v[2]*cd
+ d2;
};
bool
Optimize(
MT_Vector3& v
) const {
MT_Scalar det = Tensor().determinant();
if (MT_fuzzyZero(det)) {
return false;
}
v = -((Tensor().inverse()) * Vector());
return true;
};
};
#endif

View File

@ -1,279 +0,0 @@
/*
* ***** BEGIN GPL LICENSE BLOCK *****
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software Foundation,
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*
* The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
* All rights reserved.
*
* The Original Code is: all of this file.
*
* Contributor(s): none yet.
*
* ***** END GPL LICENSE BLOCK *****
*/
/** \file decimation/intern/LOD_QuadricEditor.cpp
* \ingroup decimation
*/
#include "LOD_QuadricEditor.h"
#include "LOD_ExternNormalEditor.h"
// Creation
///////////
using namespace std;
LOD_QuadricEditor::
LOD_QuadricEditor(
LOD_ManMesh2 &mesh
) :
m_quadrics(NULL),
m_mesh(mesh)
{
};
LOD_QuadricEditor *
LOD_QuadricEditor::
New(
LOD_ManMesh2 &mesh
){
//same number of quadrics as vertices in the mesh
MEM_SmartPtr<LOD_QuadricEditor> output(new LOD_QuadricEditor(mesh));
if (output == NULL) {
return NULL;
}
return output.Release();
}
// Property editor interface
////////////////////////////
void
LOD_QuadricEditor::
Remove(
std::vector<LOD_VertexInd> &sorted_vertices
){
vector<LOD_Quadric> & quadrics = *m_quadrics;
vector<LOD_VertexInd>::const_iterator it_start = sorted_vertices.begin();
vector<LOD_VertexInd>::const_iterator it_end = sorted_vertices.end();
for (; it_start != it_end; ++it_start) {
if (quadrics.size() > 0) {
LOD_Quadric temp = quadrics[*it_start];
quadrics[*it_start] = quadrics.back();
quadrics.back() = temp;
quadrics.pop_back();
}
}
};
// Editor specific methods
//////////////////////////
bool
LOD_QuadricEditor::
BuildQuadrics(
LOD_ExternNormalEditor& normal_editor,
bool preserve_boundaries
){
if (m_quadrics != NULL) delete(m_quadrics);
m_quadrics =new vector<LOD_Quadric> (m_mesh.VertexSet().size());
if (m_quadrics == NULL) return false;
// iterate through the face set of the mesh
// compute a quadric based upon that face and
// add it to each of it's vertices quadrics.
const vector<LOD_TriFace> &faces = m_mesh.FaceSet();
const vector<LOD_Vertex> &verts = m_mesh.VertexSet();
vector<LOD_Edge> &edges = m_mesh.EdgeSet();
const vector<MT_Vector3> &normals = normal_editor.Normals();
vector<MT_Vector3>::const_iterator normal_it = normals.begin();
vector<LOD_TriFace>::const_iterator face_it = faces.begin();
vector<LOD_TriFace>::const_iterator face_end = faces.end();
vector<LOD_Quadric> & quadrics = *m_quadrics;
for (; face_it != face_end; ++face_it, ++normal_it) {
MT_Vector3 normal = *normal_it;
MT_Scalar offset = -normal.dot(verts[face_it->m_verts[0]].pos);
LOD_Quadric q(normal,offset);
quadrics[face_it->m_verts[0]] += q;
quadrics[face_it->m_verts[1]] += q;
quadrics[face_it->m_verts[2]] += q;
}
if (preserve_boundaries) {
// iterate through the edge set and add a boundary quadric to
// each of the boundary edges vertices.
vector<LOD_Edge>::const_iterator edge_it = edges.begin();
vector<LOD_Edge>::const_iterator edge_end = edges.end();
for (; edge_it != edge_end; ++edge_it) {
if (edge_it->BoundaryEdge()) {
// compute a plane perpendicular to the edge and the normal
// of the edges single polygon.
const MT_Vector3 & v0 = verts[edge_it->m_verts[0]].pos;
const MT_Vector3 & v1 = verts[edge_it->m_verts[1]].pos;
MT_Vector3 edge_vector = v1 - v0;
LOD_FaceInd edge_face = edge_it->OpFace(LOD_EdgeInd::Empty());
edge_vector = edge_vector.cross(normals[edge_face]);
if (!edge_vector.fuzzyZero()) {
edge_vector.normalize();
LOD_Quadric boundary_q(edge_vector, - edge_vector.dot(v0));
boundary_q *= 100;
quadrics[edge_it->m_verts[0]] += boundary_q;
quadrics[edge_it->m_verts[1]] += boundary_q;
}
}
}
}
// initiate the heap keys of the edges by computing the edge costs.
vector<LOD_Edge>::iterator edge_it = edges.begin();
vector<LOD_Edge>::const_iterator edge_end = edges.end();
for (; edge_it != edge_end; ++edge_it) {
MT_Vector3 target = TargetVertex(*edge_it);
LOD_Edge &e = *edge_it;
const LOD_Quadric &q0 = quadrics[e.m_verts[0]];
const LOD_Quadric &q1 = quadrics[e.m_verts[1]];
e.HeapKey() = -float(q0.Evaluate(target) + q1.Evaluate(target));
}
return true;
};
MT_Vector3
LOD_QuadricEditor::
TargetVertex(
LOD_Edge & e
){
// compute an edge contration target for edge ei
// this is computed by summing it's vertices quadrics and
// optimizing the result.
vector<LOD_Vertex> &verts = m_mesh.VertexSet();
vector<LOD_Quadric> &quadrics = *m_quadrics;
LOD_VertexInd v0 = e.m_verts[0];
LOD_VertexInd v1 = e.m_verts[1];
LOD_Quadric q0 = quadrics[v0];
q0 += quadrics[v1];
MT_Vector3 result;
if (q0.Optimize(result)) {
return result;
} else {
// the quadric was degenerate -> just take the average of
// v0 and v1
return ((verts[v0].pos + verts[v1].pos) * 0.5);
}
};
void
LOD_QuadricEditor::
ComputeEdgeCosts(
vector<LOD_EdgeInd> &edges
){
// for each we compute the target vertex and then compute
// the quadric error e = Q1(v') + Q2(v')
vector<LOD_Edge> &edge_set = m_mesh.EdgeSet();
vector<LOD_Quadric> &quadrics = *m_quadrics;
vector<LOD_EdgeInd>::const_iterator edge_it = edges.begin();
vector<LOD_EdgeInd>::const_iterator edge_end = edges.end();
for (; edge_it != edge_end; ++edge_it) {
MT_Vector3 target = TargetVertex(edge_set[*edge_it]);
LOD_Edge &e = edge_set[*edge_it];
LOD_Quadric q0 = quadrics[e.m_verts[0]];
const LOD_Quadric &q1 = quadrics[e.m_verts[1]];
e.HeapKey() = -float(q0.Evaluate(target) + q1.Evaluate(target));
}
};

View File

@ -1,120 +0,0 @@
/*
* ***** BEGIN GPL LICENSE BLOCK *****
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software Foundation,
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*
* The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
* All rights reserved.
*
* The Original Code is: all of this file.
*
* Contributor(s): none yet.
*
* ***** END GPL LICENSE BLOCK *****
*/
/** \file decimation/intern/LOD_QuadricEditor.h
* \ingroup decimation
*/
#ifndef __LOD_QUADRICEDITOR_H__
#define __LOD_QUADRICEDITOR_H__
#include "MEM_NonCopyable.h"
#include "LOD_ManMesh2.h"
#include "MT_Vector3.h"
#include "LOD_Quadric.h"
class LOD_ExternNormalEditor;
class LOD_QuadricEditor : public MEM_NonCopyable
{
public :
// Creation
///////////
static
LOD_QuadricEditor *
New(
LOD_ManMesh2 &mesh
);
// Property editor interface
////////////////////////////
void
Remove(
std::vector<LOD_VertexInd> &sorted_vertices
);
void
Update(
std::vector<LOD_FaceInd> &sorted_vertices
);
std::vector<LOD_Quadric> &
Quadrics(
) const {
return *m_quadrics;
};
// Editor specific methods
//////////////////////////
bool
BuildQuadrics(
LOD_ExternNormalEditor& normal_editor,
bool preserve_boundaries
);
void
ComputeEdgeCosts(
std::vector<LOD_EdgeInd> &edges
);
MT_Vector3
TargetVertex(
LOD_Edge &e
);
~LOD_QuadricEditor(
){
delete(m_quadrics);
};
private :
std::vector<LOD_Quadric> * m_quadrics;
LOD_ManMesh2 &m_mesh;
private :
LOD_QuadricEditor(LOD_ManMesh2 &mesh);
};
#endif

View File

@ -1,155 +0,0 @@
/*
* ***** BEGIN GPL LICENSE BLOCK *****
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software Foundation,
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*
* The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
* All rights reserved.
*
* The Original Code is: all of this file.
*
* Contributor(s): none yet.
*
* ***** END GPL LICENSE BLOCK *****
*/
/** \file decimation/intern/LOD_decimation.cpp
* \ingroup decimation
*/
// implementation of external c api
#include "../extern/LOD_decimation.h"
#include "LOD_DecimationClass.h"
using namespace std;
int
LOD_LoadMesh(
LOD_Decimation_InfoPtr info
) {
if (info == NULL) return 0;
if (
info->vertex_buffer == NULL ||
info->vertex_normal_buffer == NULL ||
info->triangle_index_buffer == NULL
) {
return 0;
}
// create the intern object to hold all
// the decimation classes
MEM_SmartPtr<LOD_DecimationClass> intern(LOD_DecimationClass::New(info));
if (intern == NULL) return 0;
MEM_SmartPtr<vector<LOD_Vertex> > intern_vertex_buffer(new vector<LOD_Vertex>(info->vertex_num));
if (intern_vertex_buffer == NULL) return 0;
vector<LOD_Vertex>::iterator intern_vertex_it(intern_vertex_buffer->begin());
// now load in the vertices to the mesh
const int vertex_stride = 3;
float * vertex_ptr = info->vertex_buffer;
const float * vertex_end = vertex_ptr + info->vertex_num*vertex_stride;
LOD_ManMesh2 &mesh = intern->Mesh();
for (;vertex_ptr < vertex_end; vertex_ptr += vertex_stride,++intern_vertex_it) {
intern_vertex_it->pos = MT_Vector3(vertex_ptr);
}
mesh.SetVertices(intern_vertex_buffer);
// load in the triangles
const int triangle_stride = 3;
int * triangle_ptr = info->triangle_index_buffer;
const int * triangle_end = triangle_ptr + info->face_num*triangle_stride;
try {
for (;triangle_ptr < triangle_end; triangle_ptr += triangle_stride) {
mesh.AddTriangle(triangle_ptr);
}
}
catch (...) {
return 0;
}
// ok we have built the mesh
intern->m_e_decimation_state = LOD_DecimationClass::e_loaded;
info->intern = (void *) (intern.Release());
return 1;
}
int
LOD_PreprocessMesh(
LOD_Decimation_InfoPtr info
) {
if (info == NULL) return 0;
if (info->intern == NULL) return 0;
LOD_DecimationClass *intern = (LOD_DecimationClass *) info->intern;
if (intern->m_e_decimation_state != LOD_DecimationClass::e_loaded) return 0;
// arm the various internal classes so that we are ready to step
// through decimation
intern->FaceEditor().BuildNormals();
if (intern->Decimator().Arm() == false) return 0;
// ok preprocessing done
intern->m_e_decimation_state = LOD_DecimationClass::e_preprocessed;
return 1;
}
int
LOD_CollapseEdge(
LOD_Decimation_InfoPtr info
){
if (info == NULL) return 0;
if (info->intern == NULL) return 0;
LOD_DecimationClass *intern = (LOD_DecimationClass *) info->intern;
if (intern->m_e_decimation_state != LOD_DecimationClass::e_preprocessed) return 0;
bool step_result = intern->Decimator().Step();
return step_result == true ? 1 : 0;
}
int
LOD_FreeDecimationData(
LOD_Decimation_InfoPtr info
){
if (info == NULL) return 0;
if (info->intern == NULL) return 0;
LOD_DecimationClass *intern = (LOD_DecimationClass *) info->intern;
delete(intern);
info->intern = NULL;
return 1;
}

View File

@ -356,12 +356,6 @@ if(WITH_MOD_OCEANSIM)
add_definitions(-DWITH_OCEANSIM)
endif()
if(WITH_MOD_DECIMATE)
list(APPEND INC
../../../intern/decimation/extern
)
endif()
if(WITH_MOD_BOOLEAN)
list(APPEND INC
../../../intern/bsp/extern

View File

@ -10,7 +10,7 @@ sources_mask = env.Glob('intern/mask*.c')
incs = '. #/intern/guardedalloc #/intern/memutil'
incs += ' ../blenlib ../blenfont ../makesdna ../windowmanager'
incs += ' ../render/extern/include #/intern/decimation/extern ../makesrna'
incs += ' ../render/extern/include ../makesrna'
incs += ' ../imbuf ../ikplugin ../avi #/intern/elbeem/extern ../nodes ../modifiers'
incs += ' #/intern/iksolver/extern ../blenloader'
incs += ' #/extern/bullet2/src'

View File

@ -117,13 +117,6 @@ if(WITH_MOD_REMESH)
)
endif()
if(WITH_MOD_DECIMATE)
add_definitions(-DWITH_MOD_DECIMATE)
list(APPEND INC
../../../intern/decimation/extern
)
endif()
if(WITH_MOD_FLUID)
add_definitions(-DWITH_MOD_FLUID)
endif()

View File

@ -4,7 +4,7 @@ Import ('env')
sources = env.Glob('intern/*.c')
incs = '. ./intern'
incs += ' #/intern/guardedalloc #/intern/decimation/extern #/intern/bsp/extern #/intern/elbeem/extern #/extern/glew/include'
incs += ' #/intern/guardedalloc #/intern/bsp/extern #/intern/elbeem/extern #/extern/glew/include'
incs += ' ../render/extern/include ../blenloader ../bmesh'
incs += ' ../include ../blenlib ../blenfont ../makesdna ../makesrna ../blenkernel ../blenkernel/intern'
incs += ' ../gpu'
@ -20,9 +20,6 @@ if env['WITH_BF_REMESH']:
incs += ' #/intern/dualcon'
defs.append('WITH_MOD_REMESH')
if env ['WITH_BF_DECIMATE']:
defs.append('WITH_MOD_DECIMATE')
if env['WITH_BF_FLUID']:
defs.append('WITH_MOD_FLUID')

View File

@ -32,7 +32,6 @@
* \ingroup modifiers
*/
#include "DNA_meshdata_types.h"
#include "BLI_math.h"
@ -48,19 +47,12 @@
#include "BKE_cdderivedmesh.h"
#include "BKE_tessmesh.h"
#include "bmesh.h"
// #define USE_TIMEIT
/* testing only! - Campbell */
#define USE_DECIMATE_BMESH
#ifdef USE_TIMEIT
# include "PIL_time.h"
#endif
#ifdef WITH_MOD_DECIMATE
#include "LOD_decimation.h"
#endif
#include "MOD_util.h"
static void initData(ModifierData *md)
@ -78,11 +70,6 @@ static void copyData(ModifierData *md, ModifierData *target)
tdmd->percent = dmd->percent;
}
#ifdef WITH_MOD_DECIMATE
#ifdef USE_DECIMATE_BMESH
#include "bmesh.h"
static DerivedMesh *applyModifier(ModifierData *md, Object *UNUSED(ob),
DerivedMesh *derivedData,
ModifierApplyFlag UNUSED(flag))
@ -123,143 +110,6 @@ static DerivedMesh *applyModifier(ModifierData *md, Object *UNUSED(ob),
return result;
}
#else
static DerivedMesh *applyModifier(ModifierData *md, Object *UNUSED(ob),
DerivedMesh *derivedData,
ModifierApplyFlag UNUSED(flag))
{
DecimateModifierData *dmd = (DecimateModifierData *) md;
DerivedMesh *dm = derivedData, *result = NULL;
MVert *mvert;
MFace *mface;
LOD_Decimation_Info lod;
int totvert, totface;
int a, numTris;
// TIMEIT_START(decim);
DM_ensure_tessface(dm); /* BMESH - UNTIL MODIFIER IS UPDATED FOR MPoly */
mvert = dm->getVertArray(dm);
mface = dm->getTessFaceArray(dm);
totvert = dm->getNumVerts(dm);
totface = dm->getNumTessFaces(dm);
numTris = 0;
for (a = 0; a < totface; a++) {
MFace *mf = &mface[a];
numTris++;
if (mf->v4) numTris++;
}
if (numTris < 3) {
modifier_setError(md, "%s", TIP_("Modifier requires more than 3 input faces (triangles)"));
dm = CDDM_copy(dm);
return dm;
}
lod.vertex_buffer = MEM_mallocN(3 * sizeof(float) * totvert, "vertices");
lod.vertex_normal_buffer = MEM_mallocN(3 * sizeof(float) * totvert, "normals");
lod.triangle_index_buffer = MEM_mallocN(3 * sizeof(int) * numTris, "trias");
lod.vertex_num = totvert;
lod.face_num = numTris;
for (a = 0; a < totvert; a++) {
MVert *mv = &mvert[a];
float *vbCo = &lod.vertex_buffer[a * 3];
float *vbNo = &lod.vertex_normal_buffer[a * 3];
copy_v3_v3(vbCo, mv->co);
normal_short_to_float_v3(vbNo, mv->no);
}
numTris = 0;
for (a = 0; a < totface; a++) {
MFace *mf = &mface[a];
int *tri = &lod.triangle_index_buffer[3 * numTris++];
tri[0] = mf->v1;
tri[1] = mf->v2;
tri[2] = mf->v3;
if (mf->v4) {
tri = &lod.triangle_index_buffer[3 * numTris++];
tri[0] = mf->v1;
tri[1] = mf->v3;
tri[2] = mf->v4;
}
}
dmd->faceCount = 0;
if (LOD_LoadMesh(&lod) ) {
if (LOD_PreprocessMesh(&lod) ) {
/* we assume the decim_faces tells how much to reduce */
while (lod.face_num > numTris * dmd->percent) {
if (LOD_CollapseEdge(&lod) == 0) break;
}
if (lod.vertex_num > 2) {
result = CDDM_new(lod.vertex_num, 0, lod.face_num, 0, 0);
dmd->faceCount = lod.face_num;
}
else
result = CDDM_new(lod.vertex_num, 0, 0, 0, 0);
mvert = CDDM_get_verts(result);
for (a = 0; a < lod.vertex_num; a++) {
MVert *mv = &mvert[a];
float *vbCo = &lod.vertex_buffer[a * 3];
copy_v3_v3(mv->co, vbCo);
}
if (lod.vertex_num > 2) {
mface = CDDM_get_tessfaces(result);
for (a = 0; a < lod.face_num; a++) {
MFace *mf = &mface[a];
int *tri = &lod.triangle_index_buffer[a * 3];
mf->v1 = tri[0];
mf->v2 = tri[1];
mf->v3 = tri[2];
test_index_face(mf, NULL, 0, 3);
}
}
CDDM_calc_edges_tessface(result);
}
else
modifier_setError(md, "%s", TIP_("Out of memory"));
LOD_FreeDecimationData(&lod);
}
else
modifier_setError(md, "%s", TIP_("Non-manifold mesh as input"));
MEM_freeN(lod.vertex_buffer);
MEM_freeN(lod.vertex_normal_buffer);
MEM_freeN(lod.triangle_index_buffer);
// TIMEIT_END(decim);
if (result) {
CDDM_tessfaces_to_faces(result); /*builds ngon faces from tess (mface) faces*/
return result;
}
else {
return dm;
}
}
#endif // USE_DECIMATE_BMESH
#else // WITH_MOD_DECIMATE
static DerivedMesh *applyModifier(ModifierData *UNUSED(md), Object *UNUSED(ob),
DerivedMesh *derivedData,
ModifierApplyFlag UNUSED(flag))
{
return derivedData;
}
#endif // WITH_MOD_DECIMATE
ModifierTypeInfo modifierType_Decimate = {
/* name */ "Decimate",
/* structName */ "DecimateModifierData",

View File

@ -169,10 +169,6 @@ endif()
list(APPEND BLENDER_SORTED_LIBS extern_colamd)
if(WITH_MOD_DECIMATE)
list(APPEND BLENDER_SORTED_LIBS bf_intern_decimate)
endif()
if(WITH_MOD_BOOLEAN)
list(APPEND BLENDER_SORTED_LIBS bf_intern_bsp)
list(APPEND BLENDER_SORTED_LIBS bf_intern_moto)

View File

@ -60,7 +60,6 @@ struct Image;
struct ImageUser;
struct KeyingSet;
struct KeyingSetInfo;
struct LOD_Decimation_Info;
struct MCol;
struct MTex;
struct Main;

View File

@ -898,7 +898,6 @@ endif()
bf_imbuf_dds
bf_collada
bf_intern_bsp
bf_intern_decimate
bf_intern_elbeem
bf_intern_memutil
bf_intern_guardedalloc

View File

@ -34,7 +34,6 @@
# pragma warning (disable:4786)
#endif
#include "CTR_Map.h"
#include "RAS_MaterialBucket.h"
#include "STR_HashedString.h"
#include "RAS_MeshObject.h"

View File

@ -34,7 +34,6 @@
#include "MT_Transform.h"
#include "RAS_MaterialBucket.h"
#include "CTR_Map.h"
#include <vector>