mirror of
https://git.mirrors.martin98.com/https://github.com/prusa3d/PrusaSlicer.git
synced 2025-08-16 01:56:18 +08:00
refactoring of void*, crash fix
This commit is contained in:
parent
9fccbd00d0
commit
1455d0e1b3
@ -31,7 +31,9 @@
|
|||||||
#ifndef _BASICS_H
|
#ifndef _BASICS_H
|
||||||
#define _BASICS_H
|
#define _BASICS_H
|
||||||
|
|
||||||
|
#include <functional>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
|
#include <assert.h>
|
||||||
#include <math.h>
|
#include <math.h>
|
||||||
#include <time.h>
|
#include <time.h>
|
||||||
#include <limits.h>
|
#include <limits.h>
|
||||||
@ -138,163 +140,80 @@ inline void p_swap(void **a, void **b) {void *t = *a; *a = *b; *b = t;}
|
|||||||
|
|
||||||
/////////////////////////////////////////////////////////////////////////////////////////////
|
/////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
typedef int64_t j_voidint;
|
||||||
|
|
||||||
template<typename T, typename Child>
|
// void* replacement
|
||||||
class Primitive {
|
|
||||||
protected:
|
|
||||||
T value;
|
|
||||||
|
|
||||||
public:
|
|
||||||
|
|
||||||
// we must type cast to child to so
|
|
||||||
// a += 3 += 5 ... and etc.. work the same way
|
|
||||||
// as on primitives
|
|
||||||
Child &childRef(){
|
|
||||||
return *((Child*)this);
|
|
||||||
}
|
|
||||||
|
|
||||||
// you can overload to give a default value if you want
|
|
||||||
Primitive(){}
|
|
||||||
explicit Primitive(T v):value(v){}
|
|
||||||
|
|
||||||
T get(){
|
|
||||||
return value;
|
|
||||||
}
|
|
||||||
|
|
||||||
#define OP(op) Child &operator op(Child const &v){\
|
|
||||||
value op v.value; \
|
|
||||||
return childRef(); \
|
|
||||||
}\
|
|
||||||
Child &operator op(T const &v){\
|
|
||||||
value op v; \
|
|
||||||
return childRef(); \
|
|
||||||
}
|
|
||||||
|
|
||||||
// all with equals
|
|
||||||
OP(+=)
|
|
||||||
OP(-=)
|
|
||||||
OP(*=)
|
|
||||||
OP(/=)
|
|
||||||
OP(<<=)
|
|
||||||
OP(>>=)
|
|
||||||
OP(|=)
|
|
||||||
OP(^=)
|
|
||||||
OP(&=)
|
|
||||||
OP(%=)
|
|
||||||
|
|
||||||
#undef OP
|
|
||||||
|
|
||||||
#define OP(p) Child operator p(Child const &v){\
|
|
||||||
Child other = childRef();\
|
|
||||||
other p ## = v;\
|
|
||||||
return other;\
|
|
||||||
}\
|
|
||||||
Child operator p(T const &v){\
|
|
||||||
Child other = childRef();\
|
|
||||||
other p ## = v;\
|
|
||||||
return other;\
|
|
||||||
}
|
|
||||||
|
|
||||||
OP(+)
|
|
||||||
OP(-)
|
|
||||||
OP(*)
|
|
||||||
OP(/)
|
|
||||||
OP(<<)
|
|
||||||
OP(>>)
|
|
||||||
OP(|)
|
|
||||||
OP(^)
|
|
||||||
OP(&)
|
|
||||||
OP(%)
|
|
||||||
|
|
||||||
#undef OP
|
|
||||||
|
|
||||||
|
|
||||||
#define OP(p) bool operator p(Child const &v){\
|
|
||||||
return value p v.value;\
|
|
||||||
}\
|
|
||||||
bool operator p(T const &v){\
|
|
||||||
return value p v;\
|
|
||||||
}
|
|
||||||
|
|
||||||
OP(&&)
|
|
||||||
OP(||)
|
|
||||||
OP(<)
|
|
||||||
OP(<=)
|
|
||||||
OP(>)
|
|
||||||
OP(>=)
|
|
||||||
OP(==)
|
|
||||||
OP(!=)
|
|
||||||
|
|
||||||
#undef OP
|
|
||||||
|
|
||||||
Child operator +(){return Child(value);}
|
|
||||||
Child operator -(){return Child(-value);}
|
|
||||||
Child &operator ++(){++value; return childRef();}
|
|
||||||
Child operator ++(int){
|
|
||||||
Child ret(value);
|
|
||||||
++value;
|
|
||||||
return childRef();
|
|
||||||
}
|
|
||||||
Child operator --(int){
|
|
||||||
Child ret(value);
|
|
||||||
--value;
|
|
||||||
return childRef();
|
|
||||||
}
|
|
||||||
|
|
||||||
bool operator!(){return !value;}
|
|
||||||
Child operator~(){return Child(~value);}
|
|
||||||
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
class Data {
|
class Data {
|
||||||
public:
|
std::function<void(int64_t)> delete_object_func = [](int64_t){};
|
||||||
virtual ~Data() = default;
|
int64_t value = 0; // either pointer, or numeric value
|
||||||
};
|
|
||||||
|
|
||||||
class intWrapper: public Data {
|
|
||||||
private:
|
|
||||||
int val;
|
|
||||||
public:
|
|
||||||
intWrapper(int val = 0) :
|
|
||||||
val(val) {
|
|
||||||
}
|
|
||||||
operator int &() {
|
|
||||||
return val;
|
|
||||||
}
|
|
||||||
int* operator &() {
|
|
||||||
return &val;
|
|
||||||
}
|
|
||||||
operator int() const {
|
|
||||||
return val;
|
|
||||||
}
|
|
||||||
operator int*() {
|
|
||||||
return &val;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
class doubleWrapper: public Data, public Primitive<double, doubleWrapper> {
|
|
||||||
public:
|
public:
|
||||||
doubleWrapper(double val = 0) {
|
Data() {
|
||||||
this->value = val;
|
delete_object_func = [](int64_t){};
|
||||||
}
|
}
|
||||||
operator double &() {
|
|
||||||
|
Data(void* ptr) = delete;
|
||||||
|
|
||||||
|
template<typename S>
|
||||||
|
Data(S* ptr) {
|
||||||
|
delete_object_func = [](int64_t p){
|
||||||
|
delete reinterpret_cast<S*>(p);
|
||||||
|
};
|
||||||
|
value = reinterpret_cast<int64_t>(ptr);
|
||||||
|
}
|
||||||
|
|
||||||
|
operator void*() = delete;
|
||||||
|
|
||||||
|
template<typename S>
|
||||||
|
operator S*() const {
|
||||||
|
return reinterpret_cast<S*>(value);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool empty() const {
|
||||||
|
return value == 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool notEmpty() const {
|
||||||
|
return value != 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool operator==(const Data &d) const {
|
||||||
|
return value == d.value;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool operator!=(const Data &d) const {
|
||||||
|
return value != d.value;
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename S>
|
||||||
|
bool operator!=(const S* ptr) const {
|
||||||
|
return value != reinterpret_cast<int64_t>(ptr);
|
||||||
|
}
|
||||||
|
|
||||||
|
operator int64_t() const {
|
||||||
return value;
|
return value;
|
||||||
}
|
}
|
||||||
double* operator &() {
|
|
||||||
return &value;
|
Data& operator=(int64_t val) {
|
||||||
|
delete_object_func = [](int64_t){};
|
||||||
|
value = val;
|
||||||
|
return *this;
|
||||||
}
|
}
|
||||||
operator double() const {
|
|
||||||
return value;
|
void clear() {
|
||||||
|
if (value != 0) {
|
||||||
|
delete_object_func(value);
|
||||||
}
|
}
|
||||||
operator double*() {
|
forget();
|
||||||
return &value;
|
}
|
||||||
|
|
||||||
|
void forget() {
|
||||||
|
delete_object_func = [](int64_t) {};
|
||||||
|
value = 0;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
inline int to_int(Data *d) {
|
|
||||||
return static_cast<intWrapper*>(d)->operator int();
|
|
||||||
}
|
|
||||||
|
|
||||||
} //namespace T_MESH
|
} //namespace T_MESH
|
||||||
|
|
||||||
|
@ -39,7 +39,7 @@ namespace T_MESH
|
|||||||
|
|
||||||
//! Base class type for nodes of non-oriented graphs
|
//! Base class type for nodes of non-oriented graphs
|
||||||
|
|
||||||
class graphNode : public Data
|
class graphNode
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
|
||||||
@ -62,7 +62,7 @@ class graphNode : public Data
|
|||||||
|
|
||||||
//! Base class type for edges of non-oriented graphs
|
//! Base class type for edges of non-oriented graphs
|
||||||
|
|
||||||
class graphEdge : public Data
|
class graphEdge
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
|
||||||
|
@ -54,10 +54,9 @@ namespace T_MESH
|
|||||||
class abstractHeap
|
class abstractHeap
|
||||||
{
|
{
|
||||||
protected:
|
protected:
|
||||||
Data **heap; //!< Heap data is stored here
|
Data *heap; //!< Heap data is stored here
|
||||||
int numels; //!< Current number of elements
|
int numels; //!< Current number of elements
|
||||||
int maxels; //!< Maximum number of elements
|
int maxels; //!< Maximum number of elements
|
||||||
int *positions; //!< Optional pointer to an array of positions
|
|
||||||
|
|
||||||
int upheap(int i); //!< Moves the i'th object up on the heap
|
int upheap(int i); //!< Moves the i'th object up on the heap
|
||||||
int downheap(int i); //!< Moves the i'th object down on the heap
|
int downheap(int i); //!< Moves the i'th object down on the heap
|
||||||
@ -67,7 +66,7 @@ class abstractHeap
|
|||||||
//! This function must be implemented in the extended class.
|
//! This function must be implemented in the extended class.
|
||||||
//! The return value must be <0 if a<b, >0 if a>b or 0 if a=b.
|
//! The return value must be <0 if a<b, >0 if a>b or 0 if a=b.
|
||||||
|
|
||||||
virtual int compare(const Data *a, const Data *b) = 0;
|
virtual int compare(const Data& a, const Data& b) = 0;
|
||||||
|
|
||||||
public :
|
public :
|
||||||
|
|
||||||
@ -81,11 +80,11 @@ class abstractHeap
|
|||||||
//! returned, otherwise the index position of the newly inserted element is
|
//! returned, otherwise the index position of the newly inserted element is
|
||||||
//! returned.
|
//! returned.
|
||||||
|
|
||||||
int insert(Data *e);
|
int insert(const Data& e);
|
||||||
|
|
||||||
int isEmpty() const {return (numels == 0);} //!< Returns TRUE if the heap is empty
|
int isEmpty() const {return (numels == 0);} //!< Returns TRUE if the heap is empty
|
||||||
Data *getHead() const {return heap[1];} //!< Returns the first element of the heap
|
Data getHead() const {return heap[1];} //!< Returns the first element of the heap
|
||||||
Data *removeHead(); //!< Removes and returns the first element after rearranging the heap
|
Data removeHead(); //!< Removes and returns the first element after rearranging the heap
|
||||||
void flush() {numels=0;} //!< Removes all the elements
|
void flush() {numels=0;} //!< Removes all the elements
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -42,9 +42,11 @@
|
|||||||
//! compare as equal, their order in the sorted array is undefined.
|
//! compare as equal, their order in the sorted array is undefined.
|
||||||
//! See the manpage of the standard library qsort() function for further information.
|
//! See the manpage of the standard library qsort() function for further information.
|
||||||
|
|
||||||
|
#include "basics.h"
|
||||||
|
|
||||||
namespace T_MESH
|
namespace T_MESH
|
||||||
{
|
{
|
||||||
|
|
||||||
extern void jqsort(Data *v[], int numels, int (*comp)(const Data *, const Data *));
|
extern void jqsort(Data *v, int numels, int (*comp)(const Data&, const Data&));
|
||||||
|
|
||||||
} //namespace T_MESH
|
} //namespace T_MESH
|
||||||
|
@ -46,13 +46,13 @@ class Node
|
|||||||
friend class List; // This is to make methods in 'List' able to modify n_prev and n_next
|
friend class List; // This is to make methods in 'List' able to modify n_prev and n_next
|
||||||
|
|
||||||
public :
|
public :
|
||||||
Data *data; //!< Actual data stored in the node
|
Data data; //!< Actual data stored in the node
|
||||||
|
|
||||||
//! Creates an isolated node storing 'd'
|
//! Creates an isolated node storing 'd'
|
||||||
Node(const void *d) {data=(Data *)d; n_prev=n_next=NULL;}
|
Node(const Data& d) {data=d; n_prev=n_next=NULL;}
|
||||||
|
|
||||||
//! Creates a new node storing 'd' and links it to a previous node 'p' and to a next one 'n'.
|
//! Creates a new node storing 'd' and links it to a previous node 'p' and to a next one 'n'.
|
||||||
Node(const Node *p, const Data *d, const Node *n);
|
Node(const Node *p, const Data& d, const Node *n);
|
||||||
~Node(); //!< Standard destructor
|
~Node(); //!< Standard destructor
|
||||||
|
|
||||||
inline Node *prev() const {return n_prev;} //!< Returns the previous node in the list, possibly NULL
|
inline Node *prev() const {return n_prev;} //!< Returns the previous node in the list, possibly NULL
|
||||||
@ -68,7 +68,7 @@ class Node
|
|||||||
//! Doubly linked list.
|
//! Doubly linked list.
|
||||||
|
|
||||||
|
|
||||||
class List : public Data
|
class List
|
||||||
{
|
{
|
||||||
protected :
|
protected :
|
||||||
|
|
||||||
@ -82,10 +82,10 @@ class List : public Data
|
|||||||
List() {l_head = l_tail = NULL; l_numels = 0;}
|
List() {l_head = l_tail = NULL; l_numels = 0;}
|
||||||
|
|
||||||
//! Creates a list containing an element 'd' (singleton)
|
//! Creates a list containing an element 'd' (singleton)
|
||||||
List(const Data *d) {l_head = l_tail = new Node(d); l_numels = 1;}
|
List(const Data& d) {l_head = l_tail = new Node(d); l_numels = 1;}
|
||||||
|
|
||||||
//! Creates a list out of an array 'd' made of 'n' elements.
|
//! Creates a list out of an array 'd' made of 'n' elements.
|
||||||
List(const Data **d, int n);
|
List(const Data *d, int n);
|
||||||
|
|
||||||
//! Creates a duplicated list.
|
//! Creates a duplicated list.
|
||||||
List(List& l) {l_head = l_tail = NULL; l_numels = 0; appendList(&l);}
|
List(List& l) {l_head = l_tail = NULL; l_numels = 0; appendList(&l);}
|
||||||
@ -100,12 +100,12 @@ class List : public Data
|
|||||||
Node *tail() const {return l_tail;} //!< Gets the last node, NULL if empty. \n O(1).
|
Node *tail() const {return l_tail;} //!< Gets the last node, NULL if empty. \n O(1).
|
||||||
int numels() const {return l_numels;} //!< Gets the number of elements. \n O(1).
|
int numels() const {return l_numels;} //!< Gets the number of elements. \n O(1).
|
||||||
|
|
||||||
void appendHead(const Data *d); //!< Appends a new node storing 'd' to the head. \n O(1).
|
void appendHead(const Data& d); //!< Appends a new node storing 'd' to the head. \n O(1).
|
||||||
void appendTail(const Data *d); //!< Appends a new node storing 'd' to the tail. \n O(1).
|
void appendTail(const Data& d); //!< Appends a new node storing 'd' to the tail. \n O(1).
|
||||||
void insertAfter(Node *n, const Data *d); //! Inserts a new node storing 'd' right after 'n'. \n O(1).
|
void insertAfter(Node *n, const Data& d); //! Inserts a new node storing 'd' right after 'n'. \n O(1).
|
||||||
|
|
||||||
//! Deletes and removes the node containing 'd'. Returns its position, 0 if 'd' is not in the list. \n O(numels()).
|
//! Deletes and removes the node containing 'd'. Returns its position, 0 if 'd' is not in the list. \n O(numels()).
|
||||||
int removeNode(const Data *d);
|
int removeNode(const Data& d);
|
||||||
|
|
||||||
//! Deletes and i'th node (starting from 0). Returns 0 if the list has less than i+1 nodes. \n O(numels()).
|
//! Deletes and i'th node (starting from 0). Returns 0 if the list has less than i+1 nodes. \n O(numels()).
|
||||||
int removeNode(int i);
|
int removeNode(int i);
|
||||||
@ -125,12 +125,11 @@ class List : public Data
|
|||||||
//! Moves node 'n' from this list to the end of 'l'. \n O(1).
|
//! Moves node 'n' from this list to the end of 'l'. \n O(1).
|
||||||
void moveNodeTo(Node *n, List *l);
|
void moveNodeTo(Node *n, List *l);
|
||||||
|
|
||||||
Data *popHead(); //!< Deletes and removes the first node. Returns its data. \n O(1).
|
Data popHead(); //!< Deletes and removes the first node. Returns its data. \n O(1).
|
||||||
Data *popTail(); //!< Deletes and removes the last node. Returns its data. \n O(1).
|
Data popTail(); //!< Deletes and removes the last node. Returns its data. \n O(1).
|
||||||
|
|
||||||
//! Deletes and removes the node 'n' from the list and frees data memory. \n O(1).
|
//! Deletes and removes the node 'n' from the list and frees data memory. \n O(1).
|
||||||
|
|
||||||
// NOTE: The following is not true after refactoring, void* has been replaced with Data*
|
|
||||||
//! Warning. This method uses the free() function to to dispose the memory space
|
//! Warning. This method uses the free() function to to dispose the memory space
|
||||||
//! used by the data stored in the node. This means that such data should have
|
//! used by the data stored in the node. This means that such data should have
|
||||||
//! been allocated through malloc(), calloc() or realloc(), and not through the
|
//! been allocated through malloc(), calloc() or realloc(), and not through the
|
||||||
@ -144,13 +143,13 @@ class List : public Data
|
|||||||
//! Deletes and removes the node storing 'd' and frees the memory occupied by 'd' itself. \n O(numels()).
|
//! Deletes and removes the node storing 'd' and frees the memory occupied by 'd' itself. \n O(numels()).
|
||||||
|
|
||||||
//! Warning. Read the comment for the method 'freeCell()'
|
//! Warning. Read the comment for the method 'freeCell()'
|
||||||
void freeNode(Data *d);
|
void freeNode(const Data& d);
|
||||||
|
|
||||||
//! Returns the node storing 'd'. NULL if not found. \n O(numels()).
|
//! Returns the node storing 'd'. NULL if not found. \n O(numels()).
|
||||||
Node *containsNode(const Data *d) const;
|
Node *containsNode(const Data& d) const;
|
||||||
|
|
||||||
//! Replaces old_n with new_n. The Node containing new_n is returned. \n O(numels()).
|
//! Replaces old_n with new_n. The Node containing new_n is returned. \n O(numels()).
|
||||||
Node *replaceNode(const Data *old_n, const Data *new_n);
|
Node *replaceNode(const Data& old_n, const Data& new_n);
|
||||||
|
|
||||||
//! Deletes and removes all the nodes and frees data memory. \n O(numels()).
|
//! Deletes and removes all the nodes and frees data memory. \n O(numels()).
|
||||||
|
|
||||||
@ -159,7 +158,7 @@ class List : public Data
|
|||||||
|
|
||||||
void removeNodes(); //!< Deletes and removes all the nodes. \n O(numels()).
|
void removeNodes(); //!< Deletes and removes all the nodes. \n O(numels()).
|
||||||
|
|
||||||
Data **toArray() const; //!< Creates an array out of the list. \n O(numels()).
|
Data *toArray() const; //!< Creates an array out of the list. \n O(numels()).
|
||||||
|
|
||||||
//! Sorts the list using 'comp' as comparison function for two elements. \n O(numels()^2).
|
//! Sorts the list using 'comp' as comparison function for two elements. \n O(numels()^2).
|
||||||
|
|
||||||
@ -168,7 +167,7 @@ class List : public Data
|
|||||||
//! the need to have a guaranteed O(NlogN) complexity, it is possible to implement a heap
|
//! the need to have a guaranteed O(NlogN) complexity, it is possible to implement a heap
|
||||||
//! based on the 'abstractHeap' class. See the documentation of the standard 'qsort' library
|
//! based on the 'abstractHeap' class. See the documentation of the standard 'qsort' library
|
||||||
//! function for details on the prototype of the comparison function 'comp'.
|
//! function for details on the prototype of the comparison function 'comp'.
|
||||||
int sort(int (*comp)(const Data *, const Data *));
|
int sort(int (*comp)(const Data&, const Data&));
|
||||||
};
|
};
|
||||||
|
|
||||||
//! Convenience macro to scan the nodes of a list.
|
//! Convenience macro to scan the nodes of a list.
|
||||||
|
@ -68,23 +68,23 @@ PM_Rational orient2D(const PM_Rational& px, const PM_Rational& py, const PM_Rati
|
|||||||
//! of our version of the epsilon geometry for robust computation.
|
//! of our version of the epsilon geometry for robust computation.
|
||||||
|
|
||||||
|
|
||||||
class Point : public Data
|
class Point
|
||||||
{
|
{
|
||||||
public :
|
public :
|
||||||
coord x,y,z; //!< Coordinates
|
coord x,y,z; //!< Coordinates
|
||||||
Data *info; //!< Further information
|
Data info; //!< Further information
|
||||||
|
|
||||||
//! Creates a new point with coordinates (0,0,0).
|
//! Creates a new point with coordinates (0,0,0).
|
||||||
Point() {x = y = z = 0; info = NULL;}
|
Point() {x = y = z = 0; info.forget();}
|
||||||
|
|
||||||
//! Creates a new point with the same coordinates as 's'. The info field is not copied.
|
//! Creates a new point with the same coordinates as 's'. The info field is not copied.
|
||||||
Point(const Point *s) {x = s->x; y = s->y; z = s->z; info = NULL;}
|
Point(const Point *s) {x = s->x; y = s->y; z = s->z; info.forget();}
|
||||||
|
|
||||||
//! Creates a new point with the same coordinates as 's'. The info field is not copied.
|
//! Creates a new point with the same coordinates as 's'. The info field is not copied.
|
||||||
Point(const Point& s) {x = s.x; y = s.y; z = s.z; info = NULL;}
|
Point(const Point& s) {x = s.x; y = s.y; z = s.z; info.forget();}
|
||||||
|
|
||||||
//! Creates a new point with coordinates (a,b,c).
|
//! Creates a new point with coordinates (a,b,c).
|
||||||
Point(const coord& a, const coord& b, const coord& c) {x = a; y = b; z = c; info = NULL;}
|
Point(const coord& a, const coord& b, const coord& c) {x = a; y = b; z = c; info.forget();}
|
||||||
|
|
||||||
//! Do not remove this. It makes the compiler produce a vtable for this object.
|
//! Do not remove this. It makes the compiler produce a vtable for this object.
|
||||||
TMESH_VIRTUAL bool isPoint() const { return true; }
|
TMESH_VIRTUAL bool isPoint() const { return true; }
|
||||||
@ -285,7 +285,7 @@ class Point : public Data
|
|||||||
};
|
};
|
||||||
|
|
||||||
//! Lexycographic comparison to be used with jqsort() or abstractHeap.
|
//! Lexycographic comparison to be used with jqsort() or abstractHeap.
|
||||||
int xyzCompare(const Data *p1, const Data *p2);
|
int xyzCompare(const Data &p1, const Data &p2);
|
||||||
|
|
||||||
//! Static point with DBL_MAX coordinates.
|
//! Static point with DBL_MAX coordinates.
|
||||||
extern const Point INFINITE_POINT;
|
extern const Point INFINITE_POINT;
|
||||||
|
@ -38,7 +38,7 @@ namespace T_MESH
|
|||||||
#define DI_MAX_NUMBER_OF_CELLS 10000
|
#define DI_MAX_NUMBER_OF_CELLS 10000
|
||||||
#define DI_EPSILON_POINT Point(1.0e-9, 1.0e-9, 1.0e-9)
|
#define DI_EPSILON_POINT Point(1.0e-9, 1.0e-9, 1.0e-9)
|
||||||
|
|
||||||
class di_cell : public Data
|
class di_cell
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
Point mp, Mp;
|
Point mp, Mp;
|
||||||
|
@ -48,14 +48,14 @@ namespace T_MESH
|
|||||||
//! assigning up to 256 different states to the edge.
|
//! assigning up to 256 different states to the edge.
|
||||||
|
|
||||||
|
|
||||||
class Edge : public Data
|
class Edge
|
||||||
{
|
{
|
||||||
public :
|
public :
|
||||||
|
|
||||||
Vertex *v1,*v2; //!< End-points
|
Vertex *v1,*v2; //!< End-points
|
||||||
class Triangle *t1,*t2; //!< Incident triangles
|
class Triangle *t1,*t2; //!< Incident triangles
|
||||||
unsigned char mask; //!< bit-mask for marking purposes
|
unsigned char mask; //!< bit-mask for marking purposes
|
||||||
Data *info; //!< Further information
|
Data info; //!< Further information
|
||||||
|
|
||||||
|
|
||||||
Edge(); //!< AMF_ADD 1.1-2 >
|
Edge(); //!< AMF_ADD 1.1-2 >
|
||||||
@ -237,14 +237,14 @@ class Edge : public Data
|
|||||||
};
|
};
|
||||||
|
|
||||||
//! Edge comparison based on length to be used with jqsort() or abstractHeap.
|
//! Edge comparison based on length to be used with jqsort() or abstractHeap.
|
||||||
int edgeCompare(const Data *a, const Data *b);
|
int edgeCompare(const Data &a, const Data &b);
|
||||||
|
|
||||||
//! Lexycographic edge comparison to be used with jqsort() or abstractHeap.
|
//! Lexycographic edge comparison to be used with jqsort() or abstractHeap.
|
||||||
int lexEdgeCompare(const Data *a, const Data *b);
|
int lexEdgeCompare(const Data &a, const Data &b);
|
||||||
|
|
||||||
//! Vertex-based edge comparison for qsort.
|
//! Vertex-based edge comparison for qsort.
|
||||||
//! Duplicated edges are contiguous in this sorting.
|
//! Duplicated edges are contiguous in this sorting.
|
||||||
int vtxEdgeCompare(const Data *a, const Data *b);
|
int vtxEdgeCompare(const Data &a, const Data &b);
|
||||||
|
|
||||||
} //namespace T_MESH
|
} //namespace T_MESH
|
||||||
|
|
||||||
|
@ -42,7 +42,7 @@ namespace T_MESH
|
|||||||
//
|
//
|
||||||
///////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
class mc_ints : public Data
|
class mc_ints
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
|
||||||
@ -54,7 +54,7 @@ class mc_ints : public Data
|
|||||||
mc_ints(coord a, unsigned char b, Triangle *s) { ic = a; sg = b; v = NULL; source = s; }
|
mc_ints(coord a, unsigned char b, Triangle *s) { ic = a; sg = b; v = NULL; source = s; }
|
||||||
~mc_ints() { if (v) delete(v); }
|
~mc_ints() { if (v) delete(v); }
|
||||||
|
|
||||||
static int compare(const Data *e1, const Data *e2);
|
static int compare(const Data &e1, const Data &e2);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
@ -64,7 +64,7 @@ class mc_ints : public Data
|
|||||||
//
|
//
|
||||||
///////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
class mc_cell : public Data
|
class mc_cell
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
int x,y,z; // Coordinates (i.e. cell's position)
|
int x,y,z; // Coordinates (i.e. cell's position)
|
||||||
@ -77,7 +77,7 @@ class mc_cell : public Data
|
|||||||
}
|
}
|
||||||
|
|
||||||
void polygonize(Basic_TMesh *tin);
|
void polygonize(Basic_TMesh *tin);
|
||||||
static int compare(const Data *e1, const Data *e2);
|
static int compare(const Data &e1, const Data &e2);
|
||||||
|
|
||||||
void merge(mc_cell *m);
|
void merge(mc_cell *m);
|
||||||
|
|
||||||
@ -94,7 +94,7 @@ private:
|
|||||||
//
|
//
|
||||||
///////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
class mc_grid : public Data
|
class mc_grid
|
||||||
{
|
{
|
||||||
Point origin; // Origin for normalization
|
Point origin; // Origin for normalization
|
||||||
coord norm; // Normalization factor
|
coord norm; // Normalization factor
|
||||||
|
@ -104,15 +104,7 @@ class Basic_TMesh
|
|||||||
Basic_TMesh(const Triangle *t, const bool keep_ref = false);
|
Basic_TMesh(const Triangle *t, const bool keep_ref = false);
|
||||||
void init(const Triangle *t, const bool keep_ref = false);
|
void init(const Triangle *t, const bool keep_ref = false);
|
||||||
|
|
||||||
//FIXED:
|
|
||||||
//! Destructor. Frees the memory allocated for all the mesh elements.
|
//! Destructor. Frees the memory allocated for all the mesh elements.
|
||||||
//! Warning! This method uses the freeNodes() method of the class List,
|
|
||||||
//! which is not guaranteed to work correctly on systems other than
|
|
||||||
//! Linux (see the documentation of List for details).
|
|
||||||
//! Assuming that the method works correctly, however, the calling
|
|
||||||
//! function is responsible of freeing the memory that was possibly
|
|
||||||
//! allocated for objects pointed to by the 'info' field of mesh
|
|
||||||
//! elements. Clearly, this must be done before calling the destructor.
|
|
||||||
~Basic_TMesh();
|
~Basic_TMesh();
|
||||||
|
|
||||||
//! Returns true only if object is a basic Basic_TMesh. All the reimplementations must return false.
|
//! Returns true only if object is a basic Basic_TMesh. All the reimplementations must return false.
|
||||||
|
@ -46,12 +46,12 @@ namespace T_MESH
|
|||||||
//! assigning up to 256 different states to the edge.
|
//! assigning up to 256 different states to the edge.
|
||||||
|
|
||||||
|
|
||||||
class Triangle : public Data
|
class Triangle
|
||||||
{
|
{
|
||||||
public :
|
public :
|
||||||
|
|
||||||
Edge *e1, *e2, *e3; //!< Edges of the triangle
|
Edge *e1, *e2, *e3; //!< Edges of the triangle
|
||||||
Data* info; //!< Further information
|
Data info; //!< Further information
|
||||||
unsigned char mask; //!< bit-mask for marking purposes
|
unsigned char mask; //!< bit-mask for marking purposes
|
||||||
|
|
||||||
Triangle();
|
Triangle();
|
||||||
|
@ -188,15 +188,15 @@ Vertex *Basic_TMesh::checkGeometry()
|
|||||||
double ang, minda = 0;
|
double ang, minda = 0;
|
||||||
Triangle *t;
|
Triangle *t;
|
||||||
Edge *e;
|
Edge *e;
|
||||||
Vertex **varr = (Vertex **)V.toArray();
|
Data *varr = V.toArray();
|
||||||
Edge **evarr;
|
Data *evarr;
|
||||||
Vertex *v1, *v2;
|
Vertex *v1, *v2;
|
||||||
Node *n;
|
Node *n;
|
||||||
|
|
||||||
if (varr == NULL) TMesh::warning("checkGeometry: Not enough memory. Can't check for coincident vertices.\n");
|
if (varr == NULL) TMesh::warning("checkGeometry: Not enough memory. Can't check for coincident vertices.\n");
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
jqsort((Data **)varr, V.numels(), xyzCompare);
|
jqsort(varr, V.numels(), xyzCompare);
|
||||||
for (i=0; i<(V.numels()-1); i++)
|
for (i=0; i<(V.numels()-1); i++)
|
||||||
{
|
{
|
||||||
v1 = ((Vertex *)varr[i]);
|
v1 = ((Vertex *)varr[i]);
|
||||||
@ -216,11 +216,11 @@ Vertex *Basic_TMesh::checkGeometry()
|
|||||||
free(varr);
|
free(varr);
|
||||||
}
|
}
|
||||||
|
|
||||||
evarr = (Edge **)E.toArray();
|
evarr = E.toArray();
|
||||||
if (evarr == NULL) TMesh::warning("checkGeometry: Not enough memory. Can't check for coincident edges.\n");
|
if (evarr == NULL) TMesh::warning("checkGeometry: Not enough memory. Can't check for coincident edges.\n");
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
jqsort((Data **)evarr, E.numels(), lexEdgeCompare);
|
jqsort(evarr, E.numels(), lexEdgeCompare);
|
||||||
for (i=0; i<(E.numels()-1); i++)
|
for (i=0; i<(E.numels()-1); i++)
|
||||||
{
|
{
|
||||||
if (!lexEdgeCompare(evarr[i], evarr[i+1]))
|
if (!lexEdgeCompare(evarr[i], evarr[i+1]))
|
||||||
@ -278,11 +278,11 @@ int Basic_TMesh::mergeCoincidentEdges()
|
|||||||
|
|
||||||
FOREACHEDGE(e, n)
|
FOREACHEDGE(e, n)
|
||||||
{
|
{
|
||||||
if (e->v1->info != e->v1) e->v1 = (Vertex *)e->v1->info;
|
if (e->v1->info.operator !=(e->v1)) e->v1 = (Vertex *)e->v1->info;
|
||||||
if (e->v2->info != e->v2) e->v2 = (Vertex *)e->v2->info;
|
if (e->v2->info.operator !=(e->v2)) e->v2 = (Vertex *)e->v2->info;
|
||||||
e->v1->e0 = e->v2->e0 = e;
|
e->v1->e0 = e->v2->e0 = e;
|
||||||
}
|
}
|
||||||
removeVertices();
|
int rv = removeVertices();
|
||||||
|
|
||||||
// At this point the mesh should no longer have duplicated vertices, but may have duplicated edges
|
// At this point the mesh should no longer have duplicated vertices, but may have duplicated edges
|
||||||
E.sort(&vtxEdgeCompare);
|
E.sort(&vtxEdgeCompare);
|
||||||
@ -292,10 +292,11 @@ int Basic_TMesh::mergeCoincidentEdges()
|
|||||||
if (!e->isOnBoundary() || vtxEdgeCompare(e, pe)) pe = e;
|
if (!e->isOnBoundary() || vtxEdgeCompare(e, pe)) pe = e;
|
||||||
e->info = pe;
|
e->info = pe;
|
||||||
}
|
}
|
||||||
FOREACHEDGE(e, n) if (e->info != e)
|
FOREACHEDGE(e, n) if (e->info.operator !=(e))
|
||||||
{
|
{
|
||||||
Triangle *t1 = e->getBoundaryTriangle();
|
Triangle *t1 = e->getBoundaryTriangle();
|
||||||
Edge *f = ((Edge *)e->info);
|
Edge *f = ((Edge *)e->info);
|
||||||
|
Triangle *t2 = f->getBoundaryTriangle();
|
||||||
t1->replaceEdge(e, f);
|
t1->replaceEdge(e, f);
|
||||||
((f->t1 == NULL) ? (f->t1) : (f->t2)) = t1;
|
((f->t1 == NULL) ? (f->t1) : (f->t2)) = t1;
|
||||||
e->v1 = e->v2 = NULL;
|
e->v1 = e->v2 = NULL;
|
||||||
@ -343,8 +344,8 @@ bool Basic_TMesh::rebuildConnectivity(bool fixconnectivity) //!< AMF_CHANGE 1.1>
|
|||||||
Edge *e;
|
Edge *e;
|
||||||
FOREACHEDGE(e, n)
|
FOREACHEDGE(e, n)
|
||||||
{
|
{
|
||||||
if (e->v1->info != e->v1) e->v1 = (Vertex *)e->v1->info;
|
if (e->v1->info.operator !=(e->v1)) e->v1 = (Vertex *)e->v1->info;
|
||||||
if (e->v2->info != e->v2) e->v2 = (Vertex *)e->v2->info;
|
if (e->v2->info.operator !=(e->v2)) e->v2 = (Vertex *)e->v2->info;
|
||||||
e->v1->e0 = e->v2->e0 = e;
|
e->v1->e0 = e->v2->e0 = e;
|
||||||
}
|
}
|
||||||
int rv = removeVertices();
|
int rv = removeVertices();
|
||||||
@ -354,14 +355,14 @@ bool Basic_TMesh::rebuildConnectivity(bool fixconnectivity) //!< AMF_CHANGE 1.1>
|
|||||||
Triangle *t;
|
Triangle *t;
|
||||||
ExtVertex **var = new ExtVertex *[V.numels()];
|
ExtVertex **var = new ExtVertex *[V.numels()];
|
||||||
int i=0;
|
int i=0;
|
||||||
FOREACHVERTEX(v, n) { v->e0 = NULL; var[i] = new ExtVertex(v); v->info = new intWrapper(i); i++; }
|
FOREACHVERTEX(v, n) { v->e0 = NULL; var[i] = new ExtVertex(v); v->info = i; i++; }
|
||||||
int nt = T.numels();
|
int nt = T.numels();
|
||||||
int *triangles = new int[nt*3];
|
int *triangles = new int[nt*3];
|
||||||
i = 0; FOREACHTRIANGLE(t, n)
|
i = 0; FOREACHTRIANGLE(t, n)
|
||||||
{
|
{
|
||||||
triangles[i * 3] = ((intWrapper*)t->v1()->info)->operator int();
|
triangles[i * 3] = (j_voidint)t->v1()->info;
|
||||||
triangles[i*3+1] = ((intWrapper*)t->v2()->info)->operator int();
|
triangles[i*3+1] = (j_voidint)t->v2()->info;
|
||||||
triangles[i*3+2] = ((intWrapper*)t->v3()->info)->operator int();
|
triangles[i*3+2] = (j_voidint)t->v3()->info;
|
||||||
i++;
|
i++;
|
||||||
}
|
}
|
||||||
T.freeNodes();
|
T.freeNodes();
|
||||||
@ -449,7 +450,7 @@ int multiSplitEdge(Basic_TMesh *tin, Edge *e)
|
|||||||
while (splitVertices.numels())
|
while (splitVertices.numels())
|
||||||
{
|
{
|
||||||
coord ad, mind = DBL_MAX;
|
coord ad, mind = DBL_MAX;
|
||||||
Vertex *gv = nullptr;
|
Vertex *gv;
|
||||||
FOREACHVVVERTEX((&splitVertices), v, n) if ((ad = v->squaredDistance(e->v2)) < mind) { gv = v; mind = ad; }
|
FOREACHVVVERTEX((&splitVertices), v, n) if ((ad = v->squaredDistance(e->v2)) < mind) { gv = v; mind = ad; }
|
||||||
splitVertices.removeNode(gv);
|
splitVertices.removeNode(gv);
|
||||||
tin->splitEdge(e, gv);
|
tin->splitEdge(e, gv);
|
||||||
|
@ -116,13 +116,13 @@ namespace T_MESH
|
|||||||
t = (Triangle *)n->data;
|
t = (Triangle *)n->data;
|
||||||
y = (Triangle *)m->data; // For any pair (t,y) of triangles in the cell
|
y = (Triangle *)m->data; // For any pair (t,y) of triangles in the cell
|
||||||
// The same triangle pair can be in different cells. The following avoids redoing the check.
|
// The same triangle pair can be in different cells. The following avoids redoing the check.
|
||||||
if (t->info == NULL || y->info == NULL || (((List *)t->info)->containsNode(y) == NULL))
|
if (t->info.empty() || y->info.empty() || (((List *)t->info)->containsNode(y) == NULL))
|
||||||
{
|
{
|
||||||
if (t->intersects(y, justproper))
|
if (t->intersects(y, justproper))
|
||||||
{
|
{
|
||||||
MARK_VISIT(t); MARK_VISIT(y);
|
MARK_VISIT(t); MARK_VISIT(y);
|
||||||
ts = ((t->info != NULL) ? ((List *)t->info) : (new List)); ts->appendTail(y); t->info = ts;
|
ts = ((t->info.notEmpty()) ? ((List *)t->info) : (new List)); ts->appendTail(y); t->info = ts;
|
||||||
ts = ((y->info != NULL) ? ((List *)y->info) : (new List)); ts->appendTail(t); y->info = ts;
|
ts = ((y->info.notEmpty()) ? ((List *)y->info) : (new List)); ts->appendTail(t); y->info = ts;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -177,7 +177,7 @@ int Basic_TMesh::selectIntersectingTriangles(UINT16 tris_per_cell, bool justprop
|
|||||||
|
|
||||||
// Deselect everything and select only intersecting triangles
|
// Deselect everything and select only intersecting triangles
|
||||||
deselectTriangles();
|
deselectTriangles();
|
||||||
FOREACHTRIANGLE(t, n) t->info = NULL;
|
FOREACHTRIANGLE(t, n) t->info.forget();
|
||||||
i=0; FOREACHNODE(cells, n)
|
i=0; FOREACHNODE(cells, n)
|
||||||
{
|
{
|
||||||
(((di_cell *)n->data)->selectIntersections(justproper));
|
(((di_cell *)n->data)->selectIntersections(justproper));
|
||||||
@ -187,7 +187,7 @@ int Basic_TMesh::selectIntersectingTriangles(UINT16 tris_per_cell, bool justprop
|
|||||||
TMesh::end_progress();
|
TMesh::end_progress();
|
||||||
|
|
||||||
// Dispose memory allocated for cells
|
// Dispose memory allocated for cells
|
||||||
FOREACHVTTRIANGLE(selT, t, n) { if (t->info!=NULL) delete((List *)t->info); t->info = NULL; }
|
FOREACHVTTRIANGLE(selT, t, n) t->info.clear();
|
||||||
while (cells.numels()) delete((di_cell *)cells.popHead());
|
while (cells.numels()) delete((di_cell *)cells.popHead());
|
||||||
|
|
||||||
// Count selected triangles for final report and delete stored normals
|
// Count selected triangles for final report and delete stored normals
|
||||||
|
@ -580,7 +580,7 @@ int Basic_TMesh::refineSelectedHolePatches(Triangle *t0)
|
|||||||
Edge *e, *f;
|
Edge *e, *f;
|
||||||
Vertex *v;
|
Vertex *v;
|
||||||
List *ve, toswap, reg, all_edges, interior_edges, boundary_edges, boundary_vertices, interior_vertices;
|
List *ve, toswap, reg, all_edges, interior_edges, boundary_edges, boundary_vertices, interior_vertices;
|
||||||
doubleWrapper sigma, l, sv1, sv2, sv3, dv1, dv2, dv3;
|
coord sigma, l, sv1, sv2, sv3, dv1, dv2, dv3;
|
||||||
int swaps, totits, nee, ntb, nnt=-1, pnnt, gits=0;
|
int swaps, totits, nee, ntb, nnt=-1, pnnt, gits=0;
|
||||||
const double alpha = sqrt(2.0);
|
const double alpha = sqrt(2.0);
|
||||||
Point vc;
|
Point vc;
|
||||||
@ -630,7 +630,7 @@ int Basic_TMesh::refineSelectedHolePatches(Triangle *t0)
|
|||||||
{
|
{
|
||||||
ve = v->VE();
|
ve = v->VE();
|
||||||
sigma=0; nee=0; FOREACHVEEDGE(ve, e, m) if (!IS_BIT(e, 5)) {nee++; sigma += e->length();}
|
sigma=0; nee=0; FOREACHVEEDGE(ve, e, m) if (!IS_BIT(e, 5)) {nee++; sigma += e->length();}
|
||||||
sigma /= double(nee); v->info = new doubleWrapper(sigma);
|
sigma /= nee; v->info = new coord(sigma);
|
||||||
delete(ve);
|
delete(ve);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -644,9 +644,9 @@ int Basic_TMesh::refineSelectedHolePatches(Triangle *t0)
|
|||||||
FOREACHVTTRIANGLE((®), t, n)
|
FOREACHVTTRIANGLE((®), t, n)
|
||||||
{
|
{
|
||||||
vc = t->getCenter();
|
vc = t->getCenter();
|
||||||
sv1 = (*(doubleWrapper *)t->v1()->info);
|
sv1 = (*(coord *)t->v1()->info);
|
||||||
sv2 = (*(doubleWrapper *)t->v2()->info);
|
sv2 = (*(coord *)t->v2()->info);
|
||||||
sv3 = (*(doubleWrapper *)t->v3()->info);
|
sv3 = (*(coord *)t->v3()->info);
|
||||||
sigma = (sv1+sv2+sv3)/3.0;
|
sigma = (sv1+sv2+sv3)/3.0;
|
||||||
dv1 = alpha*(t->v1()->distance(&vc));
|
dv1 = alpha*(t->v1()->distance(&vc));
|
||||||
dv2 = alpha*(t->v2()->distance(&vc));
|
dv2 = alpha*(t->v2()->distance(&vc));
|
||||||
@ -658,7 +658,7 @@ int Basic_TMesh::refineSelectedHolePatches(Triangle *t0)
|
|||||||
nnt += (T.numels()-ntb);
|
nnt += (T.numels()-ntb);
|
||||||
if (T.numels() == ntb+2)
|
if (T.numels() == ntb+2)
|
||||||
{
|
{
|
||||||
v->info = new doubleWrapper(sigma);
|
v->info = new coord(sigma);
|
||||||
interior_vertices.appendHead(v);
|
interior_vertices.appendHead(v);
|
||||||
interior_edges.appendHead(v->e0);
|
interior_edges.appendHead(v->e0);
|
||||||
interior_edges.appendHead(v->e0->leftTriangle(v)->prevEdge(v->e0));
|
interior_edges.appendHead(v->e0->leftTriangle(v)->prevEdge(v->e0));
|
||||||
@ -700,8 +700,8 @@ int Basic_TMesh::refineSelectedHolePatches(Triangle *t0)
|
|||||||
} while (nnt && gits<10);
|
} while (nnt && gits<10);
|
||||||
|
|
||||||
//FOREACHVEEDGE((&boundary_edges), e, n) UNMARK_BIT(e, 6);
|
//FOREACHVEEDGE((&boundary_edges), e, n) UNMARK_BIT(e, 6);
|
||||||
FOREACHVVVERTEX((&boundary_vertices), v, n) { delete((Data *)v->info); v->info = NULL; MARK_BIT(v, 5);}
|
FOREACHVVVERTEX((&boundary_vertices), v, n) { v->info.clear(); MARK_BIT(v, 5);}
|
||||||
FOREACHVVVERTEX((&interior_vertices), v, n) { delete((Data *)v->info); v->info = NULL; MARK_BIT(v, 6);}
|
FOREACHVVVERTEX((&interior_vertices), v, n) { v->info.clear(); MARK_BIT(v, 6);}
|
||||||
|
|
||||||
if (gits>=10) {TMesh::warning("Fill holes: Refinement stage failed to converge. Breaking.\n"); return 1;}
|
if (gits>=10) {TMesh::warning("Fill holes: Refinement stage failed to converge. Breaking.\n"); return 1;}
|
||||||
|
|
||||||
|
@ -33,10 +33,10 @@
|
|||||||
namespace T_MESH
|
namespace T_MESH
|
||||||
{
|
{
|
||||||
|
|
||||||
int mc_ints::compare(const Data *e1, const Data *e2)
|
int mc_ints::compare(const Data &e1, const Data &e2)
|
||||||
{
|
{
|
||||||
mc_ints *a = (mc_ints *)e1;
|
mc_ints* a = (mc_ints*)e1;
|
||||||
mc_ints *b = (mc_ints *)e2;
|
mc_ints* b = (mc_ints*)e2;
|
||||||
coord& l1 = a->ic;
|
coord& l1 = a->ic;
|
||||||
coord& l2 = b->ic;
|
coord& l2 = b->ic;
|
||||||
if (l1 < l2) return -1;
|
if (l1 < l2) return -1;
|
||||||
@ -134,7 +134,7 @@ UBYTE mc_cell::lookdown()
|
|||||||
return i;
|
return i;
|
||||||
}
|
}
|
||||||
|
|
||||||
int mc_cell::compare(const Data *e1, const Data *e2)
|
int mc_cell::compare(const Data &e1, const Data &e2)
|
||||||
{
|
{
|
||||||
mc_cell *a = (mc_cell *)e1;
|
mc_cell *a = (mc_cell *)e1;
|
||||||
mc_cell *b = (mc_cell *)e2;
|
mc_cell *b = (mc_cell *)e2;
|
||||||
@ -680,7 +680,7 @@ void mc_cell::merge(mc_cell *m)
|
|||||||
|
|
||||||
List *mc_grid::createCells()
|
List *mc_grid::createCells()
|
||||||
{
|
{
|
||||||
int i,j,k=numrays+1;
|
int i,j,k,numcells=numrays+1;
|
||||||
mc_ints *m;
|
mc_ints *m;
|
||||||
Node *n;
|
Node *n;
|
||||||
List *ac = new List;
|
List *ac = new List;
|
||||||
@ -831,7 +831,7 @@ void mc_grid::remesh(bool simplify_result)
|
|||||||
int i=0;
|
int i=0;
|
||||||
FOREACHVTTRIANGLE((&ntin.T), t, n)
|
FOREACHVTTRIANGLE((&ntin.T), t, n)
|
||||||
{
|
{
|
||||||
sample_triangle(t); t->info=NULL;
|
sample_triangle(t); t->info.forget();
|
||||||
if (!((i++)%1000)) TMesh::report_progress("%d %% done ",(i*50)/ntin.T.numels());
|
if (!((i++)%1000)) TMesh::report_progress("%d %% done ",(i*50)/ntin.T.numels());
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -866,9 +866,9 @@ void mc_grid::remesh(bool simplify_result)
|
|||||||
|
|
||||||
FOREACHVVVERTEX((&tin->V), v, n){
|
FOREACHVVVERTEX((&tin->V), v, n){
|
||||||
|
|
||||||
v->info = NULL;
|
v->info.forget();
|
||||||
}
|
}
|
||||||
FOREACHVTTRIANGLE((&ntin.T), t, n) if (t->info) { delete ((Point *)t->info); t->info = NULL; }
|
FOREACHVTTRIANGLE((&ntin.T), t, n) t->info.clear();
|
||||||
TMesh::end_progress();
|
TMesh::end_progress();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -993,7 +993,7 @@ void mc_grid::simplify()
|
|||||||
FOREACHVVVERTEX((&tin->V), v, n)
|
FOREACHVVVERTEX((&tin->V), v, n)
|
||||||
{
|
{
|
||||||
t = ((Triangle *)v->info);
|
t = ((Triangle *)v->info);
|
||||||
if (t->info != NULL) nnor = (Point *)t->info;
|
if (t->info.notEmpty()) nnor = (Point *)t->info;
|
||||||
else t->info = nnor = new Point(t->getVector());
|
else t->info = nnor = new Point(t->getVector());
|
||||||
v->info = nnor;
|
v->info = nnor;
|
||||||
nnor->info = t;
|
nnor->info = t;
|
||||||
|
@ -37,10 +37,9 @@ namespace T_MESH
|
|||||||
|
|
||||||
abstractHeap::abstractHeap(int size)
|
abstractHeap::abstractHeap(int size)
|
||||||
{
|
{
|
||||||
heap = new Data *[size+1];
|
heap = new Data[size+1];
|
||||||
numels = 0;
|
numels = 0;
|
||||||
maxels = size;
|
maxels = size;
|
||||||
positions = NULL;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
abstractHeap::~abstractHeap()
|
abstractHeap::~abstractHeap()
|
||||||
@ -52,19 +51,15 @@ int abstractHeap::upheap(int k)
|
|||||||
{
|
{
|
||||||
if (k < 2) return k;
|
if (k < 2) return k;
|
||||||
|
|
||||||
Data *t = heap[k];
|
Data t = heap[k];
|
||||||
int fk = (k%2)?((k-1)/2):(k/2);
|
int fk = (k%2)?((k-1)/2):(k/2);
|
||||||
Data *f = heap[fk];
|
Data f = heap[fk];
|
||||||
|
|
||||||
if (compare(t, f) <= 0)
|
if (compare(t, f) <= 0)
|
||||||
{
|
{
|
||||||
heap[k] = f;
|
heap[k] = f;
|
||||||
heap[fk] = t;
|
heap[fk] = t;
|
||||||
if (positions != NULL)
|
|
||||||
{
|
|
||||||
positions[to_int(f)] = k;
|
|
||||||
positions[to_int(t)] = fk;
|
|
||||||
}
|
|
||||||
return upheap(fk);
|
return upheap(fk);
|
||||||
}
|
}
|
||||||
return k;
|
return k;
|
||||||
@ -74,45 +69,38 @@ int abstractHeap::downheap(int k)
|
|||||||
{
|
{
|
||||||
int j;
|
int j;
|
||||||
|
|
||||||
Data *t = heap[k];
|
Data t = heap[k];
|
||||||
int fk = (numels%2)?((numels-1)/2):(numels/2);
|
int fk = (numels%2)?((numels-1)/2):(numels/2);
|
||||||
if (k > fk) return k;
|
if (k > fk) return k;
|
||||||
|
|
||||||
j = k+k;
|
j = k+k;
|
||||||
if (j < numels && compare(heap[j], heap[j+1]) >= 0) j++;
|
if (j < numels && compare(heap[j], heap[j+1]) >= 0) j++;
|
||||||
Data *f = heap[j];
|
Data f = heap[j];
|
||||||
if (compare(t, f) >= 0)
|
if (compare(t, f) >= 0)
|
||||||
{
|
{
|
||||||
heap[k] = f;
|
heap[k] = f;
|
||||||
heap[j] = t;
|
heap[j] = t;
|
||||||
if (positions != NULL)
|
|
||||||
{
|
|
||||||
positions[to_int(f)] = k;
|
|
||||||
positions[to_int(t)] = j;
|
|
||||||
}
|
|
||||||
return downheap(j);
|
return downheap(j);
|
||||||
}
|
}
|
||||||
|
|
||||||
return k;
|
return k;
|
||||||
}
|
}
|
||||||
|
|
||||||
int abstractHeap::insert(Data *t)
|
int abstractHeap::insert(const Data& t)
|
||||||
{
|
{
|
||||||
if (numels == maxels) return -1;
|
if (numels == maxels) return -1;
|
||||||
|
|
||||||
heap[++numels] = t;
|
heap[++numels] = t;
|
||||||
if (positions != NULL) positions[to_int(t)] = numels;
|
|
||||||
return upheap(numels);
|
return upheap(numels);
|
||||||
}
|
}
|
||||||
|
|
||||||
Data *abstractHeap::removeHead()
|
Data abstractHeap::removeHead()
|
||||||
{
|
{
|
||||||
Data *t = heap[1];
|
Data t = heap[1];
|
||||||
if (positions != NULL) positions[to_int(t)] = 0;
|
|
||||||
heap[1] = heap[numels--];
|
heap[1] = heap[numels--];
|
||||||
if (numels)
|
if (numels)
|
||||||
{
|
{
|
||||||
if (positions != NULL) positions[to_int(heap[1])] = 1;
|
|
||||||
downheap(1);
|
downheap(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -34,8 +34,7 @@
|
|||||||
#include <vector>
|
#include <vector>
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
#endif
|
#endif
|
||||||
|
#include "jqsort.h"
|
||||||
#include "basics.h"
|
|
||||||
|
|
||||||
namespace T_MESH
|
namespace T_MESH
|
||||||
{
|
{
|
||||||
@ -70,15 +69,15 @@ void jqsort(void *v[], int numels, int(*comp)(const void *, const void *))
|
|||||||
|
|
||||||
class compobj
|
class compobj
|
||||||
{
|
{
|
||||||
int(*comp)(const Data *, const Data *);
|
int(*comp)(const Data&, const Data&);
|
||||||
|
|
||||||
public:
|
public:
|
||||||
compobj(int(*c)(const Data *, const Data *)) { comp = c; }
|
compobj(int(*c)(const Data&, const Data&)) { comp = c; }
|
||||||
|
|
||||||
bool operator()(Data *a, Data *b) { return (comp(a, b) < 0); }
|
bool operator()(const Data& a, const Data& b) { return (comp(a, b) < 0); }
|
||||||
};
|
};
|
||||||
|
|
||||||
void jqsort(Data *v[], int numels, int(*comp)(const Data *, const Data *))
|
void jqsort(Data *v, int numels, int(*comp)(const Data&, const Data&))
|
||||||
{
|
{
|
||||||
compobj a(comp);
|
compobj a(comp);
|
||||||
std::sort(v, v + numels, a);
|
std::sort(v, v + numels, a);
|
||||||
|
@ -39,9 +39,9 @@ namespace T_MESH
|
|||||||
// Create a new node containing 'd', and link it to //
|
// Create a new node containing 'd', and link it to //
|
||||||
// 'p' on the left (prev) and to 'n' on the right (next). //
|
// 'p' on the left (prev) and to 'n' on the right (next). //
|
||||||
|
|
||||||
Node::Node(const Node *p, const Data *d, const Node *n)
|
Node::Node(const Node *p, const Data& d, const Node *n)
|
||||||
{
|
{
|
||||||
data=(Data *)d;
|
data=d;
|
||||||
if ((n_prev=(Node *)p) != NULL) n_prev->n_next = this;
|
if ((n_prev=(Node *)p) != NULL) n_prev->n_next = this;
|
||||||
if ((n_next=(Node *)n) != NULL) n_next->n_prev = this;
|
if ((n_next=(Node *)n) != NULL) n_next->n_prev = this;
|
||||||
}
|
}
|
||||||
@ -58,7 +58,7 @@ Node::~Node()
|
|||||||
|
|
||||||
/////////// Constructor from list ///////////////////
|
/////////// Constructor from list ///////////////////
|
||||||
|
|
||||||
List::List(const Data **d, int n)
|
List::List(const Data *d, int n)
|
||||||
{
|
{
|
||||||
l_head = l_tail = NULL; l_numels = 0;
|
l_head = l_tail = NULL; l_numels = 0;
|
||||||
for (int i=0; i<n; i++) appendTail(d[i]);
|
for (int i=0; i<n; i++) appendTail(d[i]);
|
||||||
@ -73,21 +73,21 @@ List::~List()
|
|||||||
|
|
||||||
////////////////// Append an element //////////////////
|
////////////////// Append an element //////////////////
|
||||||
|
|
||||||
void List::appendHead(const Data *d)
|
void List::appendHead(const Data& d)
|
||||||
{
|
{
|
||||||
l_head = new Node(NULL, d, l_head);
|
l_head = new Node(NULL, d, l_head);
|
||||||
if (l_tail == NULL) l_tail = l_head;
|
if (l_tail == NULL) l_tail = l_head;
|
||||||
l_numels++;
|
l_numels++;
|
||||||
}
|
}
|
||||||
|
|
||||||
void List::appendTail(const Data *d)
|
void List::appendTail(const Data& d)
|
||||||
{
|
{
|
||||||
l_tail = new Node(l_tail, d, NULL);
|
l_tail = new Node(l_tail, d, NULL);
|
||||||
if (l_head == NULL) l_head = l_tail;
|
if (l_head == NULL) l_head = l_tail;
|
||||||
l_numels++;
|
l_numels++;
|
||||||
}
|
}
|
||||||
|
|
||||||
void List::insertAfter(Node *b, const Data *d)
|
void List::insertAfter(Node *b, const Data& d)
|
||||||
{
|
{
|
||||||
Node *nn = new Node(b, d, b->next());
|
Node *nn = new Node(b, d, b->next());
|
||||||
if (b == l_tail) l_tail = nn;
|
if (b == l_tail) l_tail = nn;
|
||||||
@ -141,25 +141,25 @@ void List::moveNodeTo(Node *n, List *l)
|
|||||||
|
|
||||||
//// Removes the first node and returns the corresponding data /////
|
//// Removes the first node and returns the corresponding data /////
|
||||||
|
|
||||||
Data *List::popHead()
|
Data List::popHead()
|
||||||
{
|
{
|
||||||
Data *data = (l_head != NULL)?(l_head->data):(NULL);
|
Data data = (l_head != NULL)?(l_head->data):(Data());
|
||||||
if (l_head != NULL) removeCell(l_head);
|
if (l_head != NULL) removeCell(l_head);
|
||||||
return data;
|
return data;
|
||||||
}
|
}
|
||||||
|
|
||||||
//// Removes the last node and returns the corresponding data /////
|
//// Removes the last node and returns the corresponding data /////
|
||||||
|
|
||||||
Data *List::popTail()
|
Data List::popTail()
|
||||||
{
|
{
|
||||||
Data *data = (l_tail != NULL)?(l_tail->data):(NULL);
|
Data data = (l_tail != NULL)?(l_tail->data):(Data());
|
||||||
if (l_tail != NULL) removeCell(l_tail);
|
if (l_tail != NULL) removeCell(l_tail);
|
||||||
return data;
|
return data;
|
||||||
}
|
}
|
||||||
|
|
||||||
//////////////////// Removes an element //////////////////
|
//////////////////// Removes an element //////////////////
|
||||||
|
|
||||||
int List::removeNode(const Data *d)
|
int List::removeNode(const Data& d)
|
||||||
{
|
{
|
||||||
Node *tmp = l_head;
|
Node *tmp = l_head;
|
||||||
int i=1;
|
int i=1;
|
||||||
@ -216,19 +216,17 @@ void List::removeCell(Node *n)
|
|||||||
|
|
||||||
void List::freeCell(Node *n)
|
void List::freeCell(Node *n)
|
||||||
{
|
{
|
||||||
delete(n->data);
|
|
||||||
removeCell(n);
|
removeCell(n);
|
||||||
}
|
}
|
||||||
|
|
||||||
void List::freeNode(Data *d)
|
void List::freeNode(const Data& d)
|
||||||
{
|
{
|
||||||
delete(d);
|
|
||||||
removeNode(d);
|
removeNode(d);
|
||||||
}
|
}
|
||||||
|
|
||||||
//////////////////// Belonging check /////////////////
|
//////////////////// Belonging check /////////////////
|
||||||
|
|
||||||
Node *List::containsNode(const Data *d) const
|
Node *List::containsNode(const Data& d) const
|
||||||
{
|
{
|
||||||
Node *tmp = l_head;
|
Node *tmp = l_head;
|
||||||
|
|
||||||
@ -241,10 +239,10 @@ Node *List::containsNode(const Data *d) const
|
|||||||
|
|
||||||
//////////////////// Replaces a node /////////////////
|
//////////////////// Replaces a node /////////////////
|
||||||
|
|
||||||
Node *List::replaceNode(const Data *od, const Data *nd)
|
Node *List::replaceNode(const Data& od, const Data& nd)
|
||||||
{
|
{
|
||||||
Node *tmp = containsNode(od);
|
Node *tmp = containsNode(od);
|
||||||
if (tmp != NULL) { tmp->data = (Data *)nd; return tmp;}
|
if (tmp != NULL) {tmp->data = nd; return tmp;}
|
||||||
appendTail(nd);
|
appendTail(nd);
|
||||||
return l_tail;
|
return l_tail;
|
||||||
}
|
}
|
||||||
@ -266,14 +264,14 @@ void List::removeNodes()
|
|||||||
|
|
||||||
///// Conversion to array ///////
|
///// Conversion to array ///////
|
||||||
|
|
||||||
Data **List::toArray() const
|
Data *List::toArray() const
|
||||||
{
|
{
|
||||||
Node *n = l_head;
|
Node *n = l_head;
|
||||||
int i;
|
int i;
|
||||||
Data **array;
|
Data *array;
|
||||||
|
|
||||||
if (l_numels == 0) return NULL;
|
if (l_numels == 0) return NULL;
|
||||||
array = (Data **)malloc(sizeof(Data *)*l_numels);
|
array = new Data[l_numels];
|
||||||
if (array == NULL) return NULL;
|
if (array == NULL) return NULL;
|
||||||
for (i=0; i<l_numels; i++, n=n->n_next) array[i] = n->data;
|
for (i=0; i<l_numels; i++, n=n->n_next) array[i] = n->data;
|
||||||
|
|
||||||
@ -282,9 +280,9 @@ Data **List::toArray() const
|
|||||||
|
|
||||||
///// Sorts the list /////////
|
///// Sorts the list /////////
|
||||||
|
|
||||||
int List::sort(int (*comp)(const Data *, const Data *))
|
int List::sort(int (*comp)(const Data&, const Data&))
|
||||||
{
|
{
|
||||||
Data **array;
|
Data *array;
|
||||||
int ne = l_numels-1;
|
int ne = l_numels-1;
|
||||||
|
|
||||||
if (l_numels < 2) return 0;
|
if (l_numels < 2) return 0;
|
||||||
@ -293,7 +291,7 @@ int List::sort(int (*comp)(const Data *, const Data *))
|
|||||||
jqsort(array, l_numels, comp);
|
jqsort(array, l_numels, comp);
|
||||||
removeNodes();
|
removeNodes();
|
||||||
for (; ne >= 0; ne--) appendHead(array[ne]);
|
for (; ne >= 0; ne--) appendHead(array[ne]);
|
||||||
free(array);
|
delete [] array;
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -34,7 +34,6 @@
|
|||||||
namespace T_MESH
|
namespace T_MESH
|
||||||
{
|
{
|
||||||
|
|
||||||
#define FABS(a) (((a)<0)?(-(a)):((a)))
|
|
||||||
|
|
||||||
//////////////////////////////////////////////////////////////////////////
|
//////////////////////////////////////////////////////////////////////////
|
||||||
//
|
//
|
||||||
|
@ -171,8 +171,8 @@ double _estm(int elen, double *e)
|
|||||||
double _adaptive2dorientation(double *pa, double *pb, double *pc, double detsum)
|
double _adaptive2dorientation(double *pa, double *pb, double *pc, double detsum)
|
||||||
{
|
{
|
||||||
double acx, acy, bcx, bcy,acxtail, acytail, bcxtail, bcytail, detleft, detright;
|
double acx, acy, bcx, bcy,acxtail, acytail, bcxtail, bcytail, detleft, detright;
|
||||||
double detlefttail, detrighttail, det, errbound, B[5], C1[8], C2[12], D[16];
|
double detlefttail, detrighttail, det, errbound, B[4], C1[8], C2[12], D[16];
|
||||||
double B3, u[5], u3, s1, t1, s0, t0, _bvr, _avr, _brn, _arn, c;
|
double B3, u[4], u3, s1, t1, s0, t0, _bvr, _avr, _brn, _arn, c;
|
||||||
double abig, ahi, alo, bhi, blo, err1, err2, err3, _i, _j, _0;
|
double abig, ahi, alo, bhi, blo, err1, err2, err3, _i, _j, _0;
|
||||||
int C1length, C2length, Dlength;
|
int C1length, C2length, Dlength;
|
||||||
|
|
||||||
|
@ -235,7 +235,7 @@ bool Point::operator<(const Point& s) const
|
|||||||
}
|
}
|
||||||
|
|
||||||
// This can be used with jqsort
|
// This can be used with jqsort
|
||||||
int xyzCompare(const Data *a, const Data *b)
|
int xyzCompare(const Data &a, const Data &b)
|
||||||
{
|
{
|
||||||
coord c;
|
coord c;
|
||||||
|
|
||||||
|
@ -29,30 +29,30 @@ bool joinClosestComponents(Basic_TMesh *tin)
|
|||||||
Triangle *t, *s;
|
Triangle *t, *s;
|
||||||
Node *n;
|
Node *n;
|
||||||
List triList, boundary_loops, *one_loop;
|
List triList, boundary_loops, *one_loop;
|
||||||
List **bloops_array;
|
Data *bloops_array;
|
||||||
int i, j, numloops;
|
int i, j, numloops;
|
||||||
|
|
||||||
// Mark triangles with connected component's unique ID
|
// Mark triangles with connected component's unique ID
|
||||||
i = 0;
|
i = 0;
|
||||||
FOREACHVTTRIANGLE((&(tin->T)), t, n) t->info = NULL;
|
FOREACHVTTRIANGLE((&(tin->T)), t, n) t->info.forget();
|
||||||
FOREACHVTTRIANGLE((&(tin->T)), t, n) if (t->info == NULL)
|
FOREACHVTTRIANGLE((&(tin->T)), t, n) if (t->info.empty())
|
||||||
{
|
{
|
||||||
i++;
|
i++;
|
||||||
triList.appendHead(t);
|
triList.appendHead(t);
|
||||||
t->info = new intWrapper(i);
|
t->info = i;
|
||||||
|
|
||||||
while (triList.numels())
|
while (triList.numels())
|
||||||
{
|
{
|
||||||
t = (Triangle *)triList.popHead();
|
t = (Triangle *)triList.popHead();
|
||||||
if ((s = t->t1()) != NULL && s->info == NULL) { triList.appendHead(s); s->info = new intWrapper(i); }
|
if ((s = t->t1()) != NULL && s->info.empty()) { triList.appendHead(s); s->info = i; }
|
||||||
if ((s = t->t2()) != NULL && s->info == NULL) { triList.appendHead(s); s->info = new intWrapper(i); }
|
if ((s = t->t2()) != NULL && s->info.empty()) { triList.appendHead(s); s->info = i; }
|
||||||
if ((s = t->t3()) != NULL && s->info == NULL) { triList.appendHead(s); s->info = new intWrapper(i); }
|
if ((s = t->t3()) != NULL && s->info.empty()) { triList.appendHead(s); s->info = i; }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (i<2)
|
if (i<2)
|
||||||
{
|
{
|
||||||
FOREACHVTTRIANGLE((&(tin->T)), t, n) t->info = NULL;
|
FOREACHVTTRIANGLE((&(tin->T)), t, n) t->info.forget();
|
||||||
// JMesh::info("Mesh is a single component. Nothing done.");
|
// JMesh::info("Mesh is a single component. Nothing done.");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@ -75,7 +75,7 @@ bool joinClosestComponents(Basic_TMesh *tin)
|
|||||||
}
|
}
|
||||||
FOREACHVVVERTEX((&(tin->V)), v, n) UNMARK_VISIT2(v);
|
FOREACHVVVERTEX((&(tin->V)), v, n) UNMARK_VISIT2(v);
|
||||||
|
|
||||||
bloops_array = (List **)boundary_loops.toArray();
|
bloops_array = boundary_loops.toArray();
|
||||||
numloops = boundary_loops.numels();
|
numloops = boundary_loops.numels();
|
||||||
|
|
||||||
int numtris = tin->T.numels();
|
int numtris = tin->T.numels();
|
||||||
@ -84,7 +84,7 @@ bool joinClosestComponents(Basic_TMesh *tin)
|
|||||||
gv = NULL;
|
gv = NULL;
|
||||||
for (i = 0; i<numloops; i++)
|
for (i = 0; i<numloops; i++)
|
||||||
for (j = 0; j<numloops; j++)
|
for (j = 0; j<numloops; j++)
|
||||||
if (((Vertex *)bloops_array[i]->head()->data)->info != ((Vertex *)bloops_array[j]->head()->data)->info)
|
if (((Vertex *)((List*)(bloops_array[i]))->head()->data)->info != ((Vertex *)((List*)(bloops_array[j]))->head()->data)->info)
|
||||||
{
|
{
|
||||||
adist = closestPair(bloops_array[i], bloops_array[j], &v, &w);
|
adist = closestPair(bloops_array[i], bloops_array[j], &v, &w);
|
||||||
if (adist<mindist) { mindist = adist; gv = v; gw = w; }
|
if (adist<mindist) { mindist = adist; gv = v; gw = w; }
|
||||||
@ -92,10 +92,10 @@ bool joinClosestComponents(Basic_TMesh *tin)
|
|||||||
|
|
||||||
if (gv != NULL) tin->joinBoundaryLoops(gv, gw, 1, 0);
|
if (gv != NULL) tin->joinBoundaryLoops(gv, gw, 1, 0);
|
||||||
|
|
||||||
FOREACHVTTRIANGLE((&(tin->T)), t, n) t->info = NULL;
|
FOREACHVTTRIANGLE((&(tin->T)), t, n) t->info.forget();
|
||||||
FOREACHVVVERTEX((&(tin->V)), v, n) v->info = NULL;
|
FOREACHVVVERTEX((&(tin->V)), v, n) v->info.forget();
|
||||||
|
|
||||||
free(bloops_array);
|
delete [] bloops_array;
|
||||||
while ((one_loop = (List *)boundary_loops.popHead()) != NULL) delete one_loop;
|
while ((one_loop = (List *)boundary_loops.popHead()) != NULL) delete one_loop;
|
||||||
|
|
||||||
return (gv != NULL);
|
return (gv != NULL);
|
||||||
|
@ -36,7 +36,7 @@ namespace T_MESH
|
|||||||
|
|
||||||
//////// Length-based edge comparison for qsort //////////
|
//////// Length-based edge comparison for qsort //////////
|
||||||
|
|
||||||
int edgeCompare(const Data *a, const Data *b)
|
int edgeCompare(const Data &a, const Data &b)
|
||||||
{
|
{
|
||||||
coord la = ((Edge *)a)->squaredLength();
|
coord la = ((Edge *)a)->squaredLength();
|
||||||
coord lb = ((Edge *)b)->squaredLength();
|
coord lb = ((Edge *)b)->squaredLength();
|
||||||
@ -50,7 +50,7 @@ int edgeCompare(const Data *a, const Data *b)
|
|||||||
|
|
||||||
//////// Lexycographic edge comparison for qsort //////////
|
//////// Lexycographic edge comparison for qsort //////////
|
||||||
|
|
||||||
int lexEdgeCompare(const Data *a, const Data *b)
|
int lexEdgeCompare(const Data& a, const Data &b)
|
||||||
{
|
{
|
||||||
Vertex *va1 = ((Edge *)a)->v1;
|
Vertex *va1 = ((Edge *)a)->v1;
|
||||||
Vertex *va2 = ((Edge *)a)->v2;
|
Vertex *va2 = ((Edge *)a)->v2;
|
||||||
@ -70,7 +70,7 @@ int lexEdgeCompare(const Data *a, const Data *b)
|
|||||||
|
|
||||||
//////// Vertex-based edge comparison for qsort //////////
|
//////// Vertex-based edge comparison for qsort //////////
|
||||||
|
|
||||||
int vtxEdgeCompare(const Data *a, const Data *b)
|
int vtxEdgeCompare(const Data &a, const Data &b)
|
||||||
{
|
{
|
||||||
Vertex *va1 = ((Edge *)a)->v1;
|
Vertex *va1 = ((Edge *)a)->v1;
|
||||||
Vertex *va2 = ((Edge *)a)->v2;
|
Vertex *va2 = ((Edge *)a)->v2;
|
||||||
@ -92,14 +92,14 @@ int vtxEdgeCompare(const Data *a, const Data *b)
|
|||||||
//!< AMF_ADD 1.1-2 >
|
//!< AMF_ADD 1.1-2 >
|
||||||
Edge::Edge(){
|
Edge::Edge(){
|
||||||
mask = 0;
|
mask = 0;
|
||||||
info = NULL;
|
info.forget();
|
||||||
}
|
}
|
||||||
Edge::Edge(Vertex *va, Vertex *vb)
|
Edge::Edge(Vertex *va, Vertex *vb)
|
||||||
{
|
{
|
||||||
v1 = va;
|
v1 = va;
|
||||||
v2 = vb;
|
v2 = vb;
|
||||||
t1 = t2 = NULL;
|
t1 = t2 = NULL;
|
||||||
info = NULL;
|
info.forget();
|
||||||
mask = 0;
|
mask = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -357,14 +357,12 @@ int Basic_TMesh::loadVRML1(const char *fname)
|
|||||||
int i,i1,i2,i3,i4,nv=0,triangulate=0;
|
int i,i1,i2,i3,i4,nv=0,triangulate=0;
|
||||||
Vertex *v;
|
Vertex *v;
|
||||||
|
|
||||||
coord cx;
|
|
||||||
|
|
||||||
if ((fp = fopen(fname,"r")) == NULL) return IO_CANTOPEN;
|
if ((fp = fopen(fname,"r")) == NULL) return IO_CANTOPEN;
|
||||||
|
|
||||||
if (!seek_keyword(fp, "point")) {closeLoadingSession(fp, 0, NULL, 0); return IO_FORMAT;}
|
if (!seek_keyword(fp, "point")) {closeLoadingSession(fp, 0, NULL, 0); return IO_FORMAT;}
|
||||||
if (!seek_keyword(fp, "[")) {closeLoadingSession(fp, 0, NULL, 0); return IO_FORMAT;}
|
if (!seek_keyword(fp, "[")) {closeLoadingSession(fp, 0, NULL, 0); return IO_FORMAT;}
|
||||||
|
|
||||||
while (fscanf(fp, "%f %f %f,", &x, &y, &z) == 3) { V.appendTail(newVertex(x, y, z)); cx = coord(x); /*printf("%f %f\n", x, cx.toFloat());*/ }
|
while (fscanf(fp, "%f %f %f,", &x, &y, &z) == 3) { V.appendTail(newVertex(x, y, z));/* cx = coord(x); printf("%f %f\n", x, cx.toFloat());*/ }
|
||||||
nv = V.numels();
|
nv = V.numels();
|
||||||
ExtVertex **var = (ExtVertex **)malloc(sizeof(ExtVertex *)*nv);
|
ExtVertex **var = (ExtVertex **)malloc(sizeof(ExtVertex *)*nv);
|
||||||
i = 0; FOREACHVERTEX(v, n) var[i++] = new ExtVertex(v);
|
i = 0; FOREACHVERTEX(v, n) var[i++] = new ExtVertex(v);
|
||||||
@ -473,7 +471,7 @@ int Basic_TMesh::loadEFF(const char *fname)
|
|||||||
Node *n;
|
Node *n;
|
||||||
char s[256];
|
char s[256];
|
||||||
coord x, y, z;
|
coord x, y, z;
|
||||||
int i, i1, i2, i3, nv=-1, nt=-1, triangulate = 0;
|
int i, i1, i2, i3, nv=-1, nt=-1;
|
||||||
Vertex *v;
|
Vertex *v;
|
||||||
|
|
||||||
|
|
||||||
@ -722,7 +720,7 @@ int Basic_TMesh::saveVRML1(const char *fname, const int mode)
|
|||||||
fprintf(fp,"Material {\n diffuseColor [\n");
|
fprintf(fp,"Material {\n diffuseColor [\n");
|
||||||
FOREACHTRIANGLE(t, n)
|
FOREACHTRIANGLE(t, n)
|
||||||
{
|
{
|
||||||
pkc = ((intWrapper*)(t->info))->operator int();
|
pkc = (unsigned int)((j_voidint)t->info);
|
||||||
fprintf(fp," %f %f %f,\n",((pkc>>24)&0x000000ff)/255.0,((pkc>>16)&0x000000ff)/255.0,((pkc>>8)&0x000000ff)/255.0);
|
fprintf(fp," %f %f %f,\n",((pkc>>24)&0x000000ff)/255.0,((pkc>>16)&0x000000ff)/255.0,((pkc>>8)&0x000000ff)/255.0);
|
||||||
}
|
}
|
||||||
fprintf(fp," ]\n}\nMaterialBinding {\n value PER_FACE_INDEXED\n}\n");
|
fprintf(fp," ]\n}\nMaterialBinding {\n value PER_FACE_INDEXED\n}\n");
|
||||||
@ -731,7 +729,7 @@ int Basic_TMesh::saveVRML1(const char *fname, const int mode)
|
|||||||
fprintf(fp,"Material {\n diffuseColor [\n");
|
fprintf(fp,"Material {\n diffuseColor [\n");
|
||||||
FOREACHVERTEX(v, n)
|
FOREACHVERTEX(v, n)
|
||||||
{
|
{
|
||||||
pkc = ((intWrapper*)(v->info))->operator int();
|
pkc = (unsigned int)((j_voidint)v->info);
|
||||||
fprintf(fp," %f %f %f,\n",((pkc>>24)&0x000000ff)/255.0,((pkc>>16)&0x000000ff)/255.0,((pkc>>8)&0x000000ff)/255.0);
|
fprintf(fp," %f %f %f,\n",((pkc>>24)&0x000000ff)/255.0,((pkc>>16)&0x000000ff)/255.0,((pkc>>8)&0x000000ff)/255.0);
|
||||||
}
|
}
|
||||||
fprintf(fp," ]\n}\nMaterialBinding {\n value PER_VERTEX_INDEXED\n}\n");
|
fprintf(fp," ]\n}\nMaterialBinding {\n value PER_VERTEX_INDEXED\n}\n");
|
||||||
@ -893,7 +891,7 @@ int Basic_TMesh::saveVerTri(const char *fname)
|
|||||||
ocds = new coord[V.numels()];
|
ocds = new coord[V.numels()];
|
||||||
i=0; FOREACHVERTEX(v, n) ocds[i++] = v->x;
|
i=0; FOREACHVERTEX(v, n) ocds[i++] = v->x;
|
||||||
i=0; FOREACHVERTEX(v, n) v->x = ++i;
|
i=0; FOREACHVERTEX(v, n) v->x = ++i;
|
||||||
i=0; FOREACHTRIANGLE(t, n) {i++; t->info = new intWrapper(i);}
|
i=0; FOREACHTRIANGLE(t, n) {i++; t->info = i;}
|
||||||
|
|
||||||
fprintf(fpt,"%d\n",T.numels());
|
fprintf(fpt,"%d\n",T.numels());
|
||||||
FOREACHTRIANGLE(t, n)
|
FOREACHTRIANGLE(t, n)
|
||||||
@ -948,13 +946,13 @@ bool Basic_TMesh::pinch(Edge *e1, bool with_common_vertex)
|
|||||||
}
|
}
|
||||||
if (n == NULL) return false;
|
if (n == NULL) return false;
|
||||||
|
|
||||||
ee->removeNode(e1); ee->removeNode(e2); e1->info = e2->info = NULL;
|
ee->removeNode(e1); ee->removeNode(e2); e1->info.forget(); e2->info.forget();
|
||||||
if (ee->numels() == 0) delete ee;
|
if (ee->numels() == 0) delete ee;
|
||||||
|
|
||||||
Edge *e, *e_1 = NULL, *e_2 = NULL;
|
Edge *e, *e_1 = NULL, *e_2 = NULL;
|
||||||
ve = e1->v1->VE();
|
ve = e1->v1->VE();
|
||||||
for (n = ve->head(); n != NULL; n = n->next()) if ((e = (Edge *)n->data)->info != NULL) { e_1 = e; break; }
|
for (n = ve->head(); n != NULL; n = n->next()) if ((e = (Edge *)n->data)->info.notEmpty()) { e_1 = e; break; }
|
||||||
for (n = ve->tail(); n != NULL; n = n->prev()) if ((e = (Edge *)n->data)->info != NULL)
|
for (n = ve->tail(); n != NULL; n = n->prev()) if ((e = (Edge *)n->data)->info.notEmpty())
|
||||||
{
|
{
|
||||||
if ((*(e->oppositeVertex(e1->v1))) != (*(e_1->oppositeVertex(e1->v1)))) e_1 = NULL;
|
if ((*(e->oppositeVertex(e1->v1))) != (*(e_1->oppositeVertex(e1->v1)))) e_1 = NULL;
|
||||||
break;
|
break;
|
||||||
@ -962,8 +960,8 @@ bool Basic_TMesh::pinch(Edge *e1, bool with_common_vertex)
|
|||||||
delete ve;
|
delete ve;
|
||||||
|
|
||||||
ve = e1->v2->VE();
|
ve = e1->v2->VE();
|
||||||
for (n = ve->head(); n != NULL; n = n->next()) if ((e = (Edge *)n->data)->info != NULL) { e_2 = e; break; }
|
for (n = ve->head(); n != NULL; n = n->next()) if ((e = (Edge *)n->data)->info.notEmpty()) { e_2 = e; break; }
|
||||||
for (n = ve->tail(); n != NULL; n = n->prev()) if ((e = (Edge *)n->data)->info != NULL)
|
for (n = ve->tail(); n != NULL; n = n->prev()) if ((e = (Edge *)n->data)->info.notEmpty())
|
||||||
{
|
{
|
||||||
if ((*(e->oppositeVertex(e1->v2))) != (*(e_2->oppositeVertex(e1->v2)))) e_2 = NULL;
|
if ((*(e->oppositeVertex(e1->v2))) != (*(e_2->oppositeVertex(e1->v2)))) e_2 = NULL;
|
||||||
break;
|
break;
|
||||||
@ -1004,7 +1002,7 @@ int Basic_TMesh::cutAndStitch()
|
|||||||
duplicateNonManifoldVertices();
|
duplicateNonManifoldVertices();
|
||||||
|
|
||||||
singular_edges.sort(&lexEdgeCompare);
|
singular_edges.sort(&lexEdgeCompare);
|
||||||
FOREACHEDGE(e1, n) e1->info = NULL;
|
FOREACHEDGE(e1, n) e1->info.forget();
|
||||||
e2 = NULL;
|
e2 = NULL;
|
||||||
FOREACHVEEDGE((&singular_edges), e1, n)
|
FOREACHVEEDGE((&singular_edges), e1, n)
|
||||||
{
|
{
|
||||||
@ -1465,7 +1463,6 @@ int Basic_TMesh::loadSTL(const char *fname)
|
|||||||
bool binary=0;
|
bool binary=0;
|
||||||
Vertex *v, *v1=NULL, *v2=NULL, *v3=NULL;
|
Vertex *v, *v1=NULL, *v2=NULL, *v3=NULL;
|
||||||
Edge *e1, *e2, *e3;
|
Edge *e1, *e2, *e3;
|
||||||
Triangle *t;
|
|
||||||
Point nor;
|
Point nor;
|
||||||
|
|
||||||
if ((fp = fopen(fname,"r")) == NULL) return IO_CANTOPEN;
|
if ((fp = fopen(fname,"r")) == NULL) return IO_CANTOPEN;
|
||||||
@ -1502,8 +1499,8 @@ int Basic_TMesh::loadSTL(const char *fname)
|
|||||||
v3 = newVertex((*((float *)(facet+36))), (*((float *)(facet+40))), (*((float *)(facet+44))));
|
v3 = newVertex((*((float *)(facet+36))), (*((float *)(facet+40))), (*((float *)(facet+44))));
|
||||||
V.appendHead(v1); V.appendHead(v2); V.appendHead(v3);
|
V.appendHead(v1); V.appendHead(v2); V.appendHead(v3);
|
||||||
e1=CreateEdge(v1, v2); e2=CreateEdge(v2, v3); e3=CreateEdge(v3, v1);
|
e1=CreateEdge(v1, v2); e2=CreateEdge(v2, v3); e3=CreateEdge(v3, v1);
|
||||||
if (Triangle(e1,e2,e3).getNormal()*nor < 0) t=CreateTriangle(e1, e3, e2);
|
if (Triangle(e1,e2,e3).getNormal()*nor < 0) CreateTriangle(e1, e3, e2);
|
||||||
else t=CreateTriangle(e1, e2, e3);
|
else CreateTriangle(e1, e2, e3);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@ -1529,8 +1526,8 @@ int Basic_TMesh::loadSTL(const char *fname)
|
|||||||
e1=CreateEdge(v1, v2);
|
e1=CreateEdge(v1, v2);
|
||||||
e2=CreateEdge(v2, v3);
|
e2=CreateEdge(v2, v3);
|
||||||
e3=CreateEdge(v3, v1);
|
e3=CreateEdge(v3, v1);
|
||||||
if (Triangle(e1,e2,e3).getNormal()*nor < 0) t=CreateTriangle(e1, e3, e2);
|
if (Triangle(e1,e2,e3).getNormal()*nor < 0) CreateTriangle(e1, e3, e2);
|
||||||
else t=CreateTriangle(e1, e2, e3);
|
else CreateTriangle(e1, e2, e3);
|
||||||
v1=v2=v3=NULL;
|
v1=v2=v3=NULL;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -187,11 +187,11 @@ void Basic_TMesh::init(const Basic_TMesh *tin, const bool clone_info)
|
|||||||
Triangle *t, *nt;
|
Triangle *t, *nt;
|
||||||
|
|
||||||
int i;
|
int i;
|
||||||
Data **t_info = new Data *[tin->T.numels()];
|
Data *t_info = new Data [tin->T.numels()];
|
||||||
i=0; FOREACHVTTRIANGLE((&(tin->T)), t, n) t_info[i++]=t->info;
|
i=0; FOREACHVTTRIANGLE((&(tin->T)), t, n) t_info[i++]=t->info;
|
||||||
Data **e_info = new Data *[tin->E.numels()];
|
Data *e_info = new Data [tin->E.numels()];
|
||||||
i=0; FOREACHVEEDGE((&(tin->E)), e, n) e_info[i++]=e->info;
|
i=0; FOREACHVEEDGE((&(tin->E)), e, n) e_info[i++]=e->info;
|
||||||
Data **v_info = new Data *[tin->V.numels()];
|
Data *v_info = new Data [tin->V.numels()];
|
||||||
i=0; FOREACHVVVERTEX((&(tin->V)), v, n) v_info[i++]=v->info;
|
i=0; FOREACHVVVERTEX((&(tin->V)), v, n) v_info[i++]=v->info;
|
||||||
|
|
||||||
FOREACHVVVERTEX((&(tin->V)), v, n)
|
FOREACHVVVERTEX((&(tin->V)), v, n)
|
||||||
@ -205,10 +205,10 @@ void Basic_TMesh::init(const Basic_TMesh *tin, const bool clone_info)
|
|||||||
FOREACHVTTRIANGLE((&(tin->T)), t, n)
|
FOREACHVTTRIANGLE((&(tin->T)), t, n)
|
||||||
{nt=newTriangle((Edge *)t->e1->info,(Edge *)t->e2->info,(Edge *)t->e3->info); T.appendTail(nt); t->info = nt;}
|
{nt=newTriangle((Edge *)t->e1->info,(Edge *)t->e2->info,(Edge *)t->e3->info); T.appendTail(nt); t->info = nt;}
|
||||||
|
|
||||||
FOREACHVVVERTEX((&(tin->V)), v, n) {((Vertex *)v->info)->e0 = (Edge *)v->e0->info; v->info = NULL;}
|
FOREACHVVVERTEX((&(tin->V)), v, n) {((Vertex *)v->info)->e0 = (Edge *)v->e0->info; v->info.forget();}
|
||||||
|
|
||||||
FOREACHVEEDGE((&(tin->E)), e, n)
|
FOREACHVEEDGE((&(tin->E)), e, n)
|
||||||
{((Edge *)e->info)->t1 = (e->t1)?((Triangle *)e->t1->info):(NULL); ((Edge *)e->info)->t2 = (e->t2)?((Triangle *)e->t2->info):(NULL); e->info = NULL;}
|
{((Edge *)e->info)->t1 = (e->t1)?((Triangle *)e->t1->info):(NULL); ((Edge *)e->info)->t2 = (e->t2)?((Triangle *)e->t2->info):(NULL); e->info.forget();}
|
||||||
|
|
||||||
i=0; FOREACHVTTRIANGLE((&(tin->T)), t, n) t->info=t_info[i++];
|
i=0; FOREACHVTTRIANGLE((&(tin->T)), t, n) t->info=t_info[i++];
|
||||||
i=0; FOREACHVEEDGE((&(tin->E)), e, n) e->info=e_info[i++];
|
i=0; FOREACHVEEDGE((&(tin->E)), e, n) e->info=e_info[i++];
|
||||||
@ -280,9 +280,9 @@ void Basic_TMesh::init(const Triangle *t0, const bool keep_reference)
|
|||||||
|
|
||||||
if (!keep_reference)
|
if (!keep_reference)
|
||||||
{
|
{
|
||||||
FOREACHVVVERTEX((&sv), v, n) v->info = NULL;
|
FOREACHVVVERTEX((&sv), v, n) v->info.forget();
|
||||||
FOREACHVEEDGE((&se), e, n) e->info = NULL;
|
FOREACHVEEDGE((&se), e, n) e->info.forget();
|
||||||
FOREACHVTTRIANGLE((&st), t, n) t->info = NULL;
|
FOREACHVTTRIANGLE((&st), t, n) t->info.forget();
|
||||||
}
|
}
|
||||||
|
|
||||||
eulerUpdate();
|
eulerUpdate();
|
||||||
@ -428,11 +428,10 @@ Edge *Basic_TMesh::bridgeBoundaries(Edge *gve, Edge *gwe)
|
|||||||
{
|
{
|
||||||
if (gve == gwe || !gve->isOnBoundary() || !gwe->isOnBoundary()) return NULL;
|
if (gve == gwe || !gve->isOnBoundary() || !gwe->isOnBoundary()) return NULL;
|
||||||
|
|
||||||
Triangle *t;
|
|
||||||
Vertex *v = gve->commonVertex(gwe);
|
Vertex *v = gve->commonVertex(gwe);
|
||||||
if (v != NULL)
|
if (v != NULL)
|
||||||
{
|
{
|
||||||
t = EulerEdgeTriangle(gve, gwe);
|
EulerEdgeTriangle(gve, gwe);
|
||||||
return gve;
|
return gve;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -445,8 +444,8 @@ Edge *Basic_TMesh::bridgeBoundaries(Edge *gve, Edge *gwe)
|
|||||||
Edge *je2 = CreateEdge(gwn, gvn);
|
Edge *je2 = CreateEdge(gwn, gvn);
|
||||||
Edge *je1 = CreateEdge(gv, gwn);
|
Edge *je1 = CreateEdge(gv, gwn);
|
||||||
|
|
||||||
t = CreateTriangle(je, gwe, je1);
|
CreateTriangle(je, gwe, je1);
|
||||||
t = CreateTriangle(je1, je2, gve);
|
CreateTriangle(je1, je2, gve);
|
||||||
|
|
||||||
return je1;
|
return je1;
|
||||||
}
|
}
|
||||||
@ -838,14 +837,14 @@ Basic_TMesh *Basic_TMesh::createSubMeshFromSelection(Triangle *t0, bool keep_ref
|
|||||||
FOREACHVEEDGE((&sE), e, n) e->v1->e0 = e->v2->e0 = e;
|
FOREACHVEEDGE((&sE), e, n) e->v1->e0 = e->v2->e0 = e;
|
||||||
|
|
||||||
int i;
|
int i;
|
||||||
Data **v_info = NULL, **e_info = NULL, **t_info = NULL;
|
Data *v_info = NULL, *e_info = NULL, *t_info = NULL;
|
||||||
if (!keep_ref)
|
if (!keep_ref)
|
||||||
{
|
{
|
||||||
v_info = new Data *[sV.numels()];
|
v_info = new Data [sV.numels()];
|
||||||
i=0; FOREACHVVVERTEX((&sV), v, n) v_info[i++] = v->info;
|
i=0; FOREACHVVVERTEX((&sV), v, n) v_info[i++] = v->info;
|
||||||
e_info = new Data *[sE.numels()];
|
e_info = new Data [sE.numels()];
|
||||||
i=0; FOREACHVEEDGE((&sE), e, n) e_info[i++] = e->info;
|
i=0; FOREACHVEEDGE((&sE), e, n) e_info[i++] = e->info;
|
||||||
t_info = new Data *[sT.numels()];
|
t_info = new Data [sT.numels()];
|
||||||
i=0; FOREACHVTTRIANGLE((&sT), t, n) t_info[i++] = t->info;
|
i=0; FOREACHVTTRIANGLE((&sT), t, n) t_info[i++] = t->info;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1850,7 +1849,7 @@ void Basic_TMesh::openToDisk()
|
|||||||
|
|
||||||
FOREACHEDGE(e, n) UNMARK_BIT(e, 3);
|
FOREACHEDGE(e, n) UNMARK_BIT(e, 3);
|
||||||
|
|
||||||
FOREACHVERTEX(v, n) if (v->info) {delete(((List *)v->info)); v->info = NULL;}
|
FOREACHVERTEX(v, n) v->info.clear();
|
||||||
duplicateNonManifoldVertices();
|
duplicateNonManifoldVertices();
|
||||||
d_boundaries = d_handles = d_shells = 1;
|
d_boundaries = d_handles = d_shells = 1;
|
||||||
}
|
}
|
||||||
|
@ -41,7 +41,7 @@ extern "C" double orient2d(double *, double *, double *);
|
|||||||
//!< AMF_ADD 1.1>
|
//!< AMF_ADD 1.1>
|
||||||
Triangle::Triangle(){
|
Triangle::Triangle(){
|
||||||
mask = 0;
|
mask = 0;
|
||||||
info = NULL;
|
info.forget();
|
||||||
}
|
}
|
||||||
|
|
||||||
Triangle::Triangle(Edge *a, Edge *b, Edge *c)
|
Triangle::Triangle(Edge *a, Edge *b, Edge *c)
|
||||||
@ -50,7 +50,7 @@ Triangle::Triangle(Edge *a, Edge *b, Edge *c)
|
|||||||
e2 = b;
|
e2 = b;
|
||||||
e3 = c;
|
e3 = c;
|
||||||
mask = 0;
|
mask = 0;
|
||||||
info = NULL;
|
info.forget();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -50,8 +50,6 @@ namespace detail {
|
|||||||
|
|
||||||
using namespace T_MESH;
|
using namespace T_MESH;
|
||||||
|
|
||||||
static int ensure_tmesh_initialization = (TMesh::init(), 0);
|
|
||||||
|
|
||||||
double closestPair(List *bl1, List *bl2, Vertex **closest_on_bl1, Vertex **closest_on_bl2)
|
double closestPair(List *bl1, List *bl2, Vertex **closest_on_bl1, Vertex **closest_on_bl2)
|
||||||
{
|
{
|
||||||
Node *n, *m;
|
Node *n, *m;
|
||||||
@ -76,30 +74,29 @@ bool joinClosestComponents(Basic_TMesh *tin)
|
|||||||
Triangle *t, *s;
|
Triangle *t, *s;
|
||||||
Node *n;
|
Node *n;
|
||||||
List triList, boundary_loops, *one_loop;
|
List triList, boundary_loops, *one_loop;
|
||||||
List **bloops_array;
|
Data *bloops_array;
|
||||||
int i, j, numloops;
|
int i, j, numloops;
|
||||||
|
|
||||||
// Mark triangles with connected component's unique ID
|
// Mark triangles with connected component's unique ID
|
||||||
i = 0;
|
i = 0;
|
||||||
FOREACHVTTRIANGLE((&(tin->T)), t, n) t->info = NULL;
|
FOREACHVTTRIANGLE((&(tin->T)), t, n) t->info = Data();
|
||||||
FOREACHVTTRIANGLE((&(tin->T)), t, n) if (t->info == NULL)
|
FOREACHVTTRIANGLE((&(tin->T)), t, n) if (t->info == Data())
|
||||||
{
|
{
|
||||||
i++;
|
i++;
|
||||||
triList.appendHead(t);
|
triList.appendHead(t);
|
||||||
t->info = new intWrapper(i);
|
|
||||||
|
|
||||||
while (triList.numels())
|
while (triList.numels())
|
||||||
{
|
{
|
||||||
t = (Triangle *)triList.popHead();
|
t = (Triangle *)triList.popHead();
|
||||||
if ((s = t->t1()) != NULL && s->info == NULL) {triList.appendHead(s); s->info = new intWrapper(i);}
|
if ((s = t->t1()) != NULL && s->info.empty()) {triList.appendHead(s); s->info = i;}
|
||||||
if ((s = t->t2()) != NULL && s->info == NULL) {triList.appendHead(s); s->info = new intWrapper(i);}
|
if ((s = t->t2()) != NULL && s->info.empty()) {triList.appendHead(s); s->info = i;}
|
||||||
if ((s = t->t3()) != NULL && s->info == NULL) {triList.appendHead(s); s->info = new intWrapper(i);}
|
if ((s = t->t3()) != NULL && s->info.empty()) {triList.appendHead(s); s->info = i;}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (i<2)
|
if (i<2)
|
||||||
{
|
{
|
||||||
FOREACHVTTRIANGLE((&(tin->T)), t, n) t->info = NULL;
|
FOREACHVTTRIANGLE((&(tin->T)), t, n) t->info = Data();
|
||||||
// JMesh::info("Mesh is a single component. Nothing done.");
|
// JMesh::info("Mesh is a single component. Nothing done.");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@ -122,7 +119,7 @@ bool joinClosestComponents(Basic_TMesh *tin)
|
|||||||
}
|
}
|
||||||
FOREACHVVVERTEX((&(tin->V)), v, n) UNMARK_VISIT2(v);
|
FOREACHVVVERTEX((&(tin->V)), v, n) UNMARK_VISIT2(v);
|
||||||
|
|
||||||
bloops_array = (List **)boundary_loops.toArray();
|
bloops_array = boundary_loops.toArray();
|
||||||
numloops = boundary_loops.numels();
|
numloops = boundary_loops.numels();
|
||||||
|
|
||||||
double adist,
|
double adist,
|
||||||
@ -131,7 +128,7 @@ bool joinClosestComponents(Basic_TMesh *tin)
|
|||||||
gv = NULL;
|
gv = NULL;
|
||||||
for (i = 0; i < numloops; i++)
|
for (i = 0; i < numloops; i++)
|
||||||
for (j = 0; j < numloops; j++)
|
for (j = 0; j < numloops; j++)
|
||||||
if (((Vertex*) bloops_array[i]->head()->data)->info != ((Vertex*) bloops_array[j]->head()->data)->info)
|
if (((Vertex*)((List*)(bloops_array[i]))->head()->data)->info != ((Vertex*) ((List*)(bloops_array[j]))->head()->data)->info)
|
||||||
{
|
{
|
||||||
adist = closestPair(bloops_array[i], bloops_array[j], &v, &w);
|
adist = closestPair(bloops_array[i], bloops_array[j], &v, &w);
|
||||||
if (adist < mindist) {
|
if (adist < mindist) {
|
||||||
@ -145,12 +142,12 @@ bool joinClosestComponents(Basic_TMesh *tin)
|
|||||||
tin->joinBoundaryLoops(gv, gw, 1, 0);
|
tin->joinBoundaryLoops(gv, gw, 1, 0);
|
||||||
|
|
||||||
FOREACHVTTRIANGLE((&(tin->T)), t, n)
|
FOREACHVTTRIANGLE((&(tin->T)), t, n)
|
||||||
t->info = NULL;
|
t->info.clear();
|
||||||
FOREACHVVVERTEX((&(tin->V)), v, n)
|
FOREACHVVVERTEX((&(tin->V)), v, n)
|
||||||
v->info = NULL;
|
v->info.clear();
|
||||||
|
|
||||||
free(bloops_array);
|
delete [] bloops_array;
|
||||||
while ((one_loop = (List*) boundary_loops.popHead()) != NULL)
|
while ((one_loop = (List*) boundary_loops.popHead()) != Data())
|
||||||
delete one_loop;
|
delete one_loop;
|
||||||
|
|
||||||
return (gv != NULL);
|
return (gv != NULL);
|
||||||
@ -159,7 +156,6 @@ bool joinClosestComponents(Basic_TMesh *tin)
|
|||||||
class Basic_TMesh_Adapter: public Basic_TMesh {
|
class Basic_TMesh_Adapter: public Basic_TMesh {
|
||||||
public:
|
public:
|
||||||
void load_indexed_triangle_set(const indexed_triangle_set &its) {
|
void load_indexed_triangle_set(const indexed_triangle_set &its) {
|
||||||
|
|
||||||
for (const auto &vertex : its.vertices) {
|
for (const auto &vertex : its.vertices) {
|
||||||
this->V.appendTail(this->newVertex(vertex.x(), vertex.y(), vertex.z()));
|
this->V.appendTail(this->newVertex(vertex.x(), vertex.y(), vertex.z()));
|
||||||
}
|
}
|
||||||
@ -241,6 +237,7 @@ private:
|
|||||||
free(tmp);
|
free(tmp);
|
||||||
}
|
}
|
||||||
fixConnectivity();
|
fixConnectivity();
|
||||||
|
// rebuildConnectivity(true);
|
||||||
this->d_boundaries = this->d_handles = this->d_shells = 1;
|
this->d_boundaries = this->d_handles = this->d_shells = 1;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
@ -279,6 +276,7 @@ bool fix_model_by_meshfix(ModelObject &model_object, int volume_idx, wxProgressD
|
|||||||
auto worker_thread = boost::thread(
|
auto worker_thread = boost::thread(
|
||||||
[&model_object, &volumes, &ivolume, on_progress, &success, &canceled, &finished]() {
|
[&model_object, &volumes, &ivolume, on_progress, &success, &canceled, &finished]() {
|
||||||
try {
|
try {
|
||||||
|
T_MESH::TMesh::init(); // TODO call only once (but it seems that multiple calls do not break it)
|
||||||
std::vector<TriangleMesh> meshes_repaired;
|
std::vector<TriangleMesh> meshes_repaired;
|
||||||
meshes_repaired.reserve(volumes.size());
|
meshes_repaired.reserve(volumes.size());
|
||||||
for (ModelVolume *mv : volumes) {
|
for (ModelVolume *mv : volumes) {
|
||||||
@ -296,7 +294,7 @@ bool fix_model_by_meshfix(ModelObject &model_object, int volume_idx, wxProgressD
|
|||||||
on_progress(L("Join closest components"), unsigned(progress_part_base + 0.1 * percent_per_part));
|
on_progress(L("Join closest components"), unsigned(progress_part_base + 0.1 * percent_per_part));
|
||||||
if (canceled)
|
if (canceled)
|
||||||
throw RepairCanceledException();
|
throw RepairCanceledException();
|
||||||
joinClosestComponents(&tin);
|
while (joinClosestComponents(&tin)) (tin.shells());
|
||||||
tin.deselectTriangles();
|
tin.deselectTriangles();
|
||||||
tin.boundaries();
|
tin.boundaries();
|
||||||
// Keep only the largest component (i.e. with most triangles)
|
// Keep only the largest component (i.e. with most triangles)
|
||||||
|
Loading…
x
Reference in New Issue
Block a user