Commit 87514d49 authored by Dmitry Bagaev's avatar Dmitry Bagaev
Browse files

Merge remote-tracking branch 'INMOST-DEV/master' into fixfc2

# Conflicts:
#	Source/Solver/solver.cpp
#	Source/Solver/solver_bcgsl.hpp
parents fcd37404 0e99faa2
......@@ -41,6 +41,7 @@ bool drawaxis = true, drawcolorbar = true;
Element disp_e;
Mesh::GeomParam table;
ElementArray<Element> orphans;
int is_material_defined = 0;
#define CLIP_NONE 0
#define CLIP_NODE 1
......@@ -55,6 +56,10 @@ ElementArray<Element> orphans;
Storage::real p[3] = {0,0,0}, n[3] = {0,0,1};
ElementArray<Element> boundary_faces;
ElementArray<Edge> added_edges;
std::map<int,std::vector<HandleType> > material_faces;
std::map<int,double> material_x;
std::map<int,double> material_y;
std::map<int,double> material_z;
std::vector<double> harmonic_points, dual_harmonic_points, conormals;
......@@ -1031,6 +1036,18 @@ class face2gl
color_t cntcolor;
double cnttexcoord;
public:
void shift(double x, double y, double z)
{
cnt[0] += x;
cnt[1] += y;
cnt[2] += z;
for(size_t k = 0; k < verts.size(); k+=3)
{
verts[k+0] += x;
verts[k+1] += y;
verts[k+2] += z;
}
}
static void radix_sort_dist(std::vector<face2gl> & set)
{
static std::vector<face2gl> tmp;
......@@ -1281,7 +1298,7 @@ public:
double px,py,z;
file << "<g stroke=\"black\">" << std::endl;
file << "<polyline fill=\"none\" points=\"";
for(unsigned k = 0; k < verts.size(); k+=3)
for(unsigned k = 0; k < verts.size()+3; k+=3)
{
gluProject(verts[k%verts.size()+0],verts[k%verts.size()+1],verts[k%verts.size()+2],modelview,projection,viewport,&px,&py,&z); py = height-py;
file << px << "," << py << " ";
......@@ -3599,7 +3616,7 @@ void keyboard(unsigned char key, int x, int y)
}
else if( key == 'e' )
{
drawedges = (drawedges+1)%4;
drawedges = (drawedges+1)%(4+is_material_defined);
glutPostRedisplay();
}
else if( key == 'w' )
......@@ -4252,10 +4269,27 @@ void draw_screen()
//glTranslated((l+r)*0.5,(b+t)*0.5,(near+far)*0.5);
if( drawedges == 4 )
{
clip_boundary.clear();
for(std::map<int,std::vector<HandleType> >::iterator it = material_faces.begin(); it != material_faces.end(); ++it)
{
for(std::vector<HandleType>::iterator jt = it->second.begin(); jt != it->second.end(); ++jt)
{
clip_boundary.push_back(DrawFace(Face(mesh,*jt)));
clip_boundary.back().shift(material_x[it->first],material_y[it->first],material_z[it->first]);
clip_boundary.back().set_color(0.6,0.6,0.6,1);
}
}
draw_faces(clip_boundary);
glColor4f(0,0,0,1);
draw_edges(clip_boundary);
clipboxupdate = true;
}
else
{
if( oclipper )
if( oclipper )
{
if( clipupdate )
......@@ -4572,20 +4606,33 @@ void draw_screen()
if( k < slen && l < slen && l+1 < slen )
{
bool is_number = true;
for(int r = l+1; r < slen; ++r)
if( !isdigit(visualization_prompt[r]) )
is_number = false;
if( !is_number ) for(int r = l+1; r < slen; ++r) visualization_prompt[r] = tolower(visualization_prompt[r]);
strcpy(typen,visualization_prompt);
strcpy(name,visualization_prompt+k+1);
comp = atoi(visualization_prompt+l+1);
if( is_number )
comp = atoi(visualization_prompt+l+1);
else if( std::string(visualization_prompt+l+1) == "mag" )
comp = ENUMUNDEF;
else
{
std::cout << "unknown name for component, expected number or 'mag'" << std::endl;
comp = ENUMUNDEF-1;
}
visualization_prompt[k] = ':';
visualization_prompt[l] = ':';
printf("type %s name %s comp %d\n",typen,name,comp);
std::string stype(typen), sname(name);
if( mesh->HaveTag(sname) )
if( mesh->HaveTag(sname) && comp != ENUMUNDEF-1)
{
Tag source_tag = mesh->GetTag(sname);
if( source_tag.GetDataType() == DATA_REAL || source_tag.GetDataType() == DATA_INTEGER )
{
if( comp >= 0 && comp < source_tag.GetSize() )
if( (comp >= 0 && comp < source_tag.GetSize()) || comp == ENUMUNDEF )
{
visualization_type = NONE;
for(size_t q = 0; q < stype.size(); ++q)
......@@ -4622,12 +4669,35 @@ void draw_screen()
Storage::real_array coords = it->Coords();
Storage::real cnt[3], dist, wgt;
Storage::real val = 0.0, vol = 0.0, res;
for(ElementArray<Element>::iterator jt = elems.begin(); jt != elems.end(); ++jt) if( jt->HaveData(source_tag) && jt->GetDataSize(source_tag) > comp )
for(ElementArray<Element>::iterator jt = elems.begin(); jt != elems.end(); ++jt) if( jt->HaveData(source_tag) && (jt->GetDataSize(source_tag) > comp || comp == ENUMUNDEF) )
{
jt->Centroid(cnt);
dist = (cnt[0]-coords[0])*(cnt[0]-coords[0])+(cnt[1]-coords[1])*(cnt[1]-coords[1])+(cnt[2]-coords[2])*(cnt[2]-coords[2]);
wgt = 1.0/(dist+1.0e-8);
val += wgt * (source_tag.GetDataType() == DATA_REAL ? jt->RealArray(source_tag)[comp] : static_cast<Storage::real>(jt->IntegerArray(source_tag)[comp]) );
if( source_tag.GetDataType() == DATA_REAL )
{
Storage::real_array v = jt->RealArray(source_tag);
if( comp == ENUMUNDEF )
{
double l = 0;
for(unsigned q = 0; q < v.size(); ++q) l += v[q]*v[q];
l = sqrt(l);
val += wgt * l;
}
else val += wgt * v[comp];
}
else if( source_tag.GetDataType() == DATA_INTEGER )
{
Storage::integer_array v = jt->IntegerArray(source_tag);
if( comp == ENUMUNDEF )
{
double l = 0;
for(unsigned q = 0; q < v.size(); ++q) l += v[q]*v[q];
l = sqrt(l);
val += wgt * l;
}
else val += wgt * v[comp];
}
vol += wgt;
}
res = val/vol;
......@@ -4643,12 +4713,35 @@ void draw_screen()
it->Centroid(coords);
Storage::real cnt[3], dist, wgt;
Storage::real val = 0.0, vol = 0.0, res;
for(ElementArray<Element>::iterator jt = elems.begin(); jt != elems.end(); ++jt) if( jt->HaveData(source_tag) && jt->GetDataSize(source_tag) > comp )
for(ElementArray<Element>::iterator jt = elems.begin(); jt != elems.end(); ++jt) if( jt->HaveData(source_tag) && (jt->GetDataSize(source_tag) > comp || comp == ENUMUNDEF) )
{
jt->Centroid(cnt);
dist = (cnt[0]-coords[0])*(cnt[0]-coords[0])+(cnt[1]-coords[1])*(cnt[1]-coords[1])+(cnt[2]-coords[2])*(cnt[2]-coords[2]);
wgt = 1.0/(dist+1.0e-8);
val += wgt * (source_tag.GetDataType() == DATA_REAL ? jt->RealArray(source_tag)[comp] : static_cast<Storage::real>(jt->IntegerArray(source_tag)[comp]) );
if( source_tag.GetDataType() == DATA_REAL )
{
Storage::real_array v = jt->RealArray(source_tag);
if( comp == ENUMUNDEF )
{
double l = 0;
for(unsigned q = 0; q < v.size(); ++q) l += v[q]*v[q];
l = sqrt(l);
val += wgt * l;
}
else val += wgt * v[comp];
}
else if( source_tag.GetDataType() == DATA_INTEGER )
{
Storage::integer_array v = jt->IntegerArray(source_tag);
if( comp == ENUMUNDEF )
{
double l = 0;
for(unsigned q = 0; q < v.size(); ++q) l += v[q]*v[q];
l = sqrt(l);
val += wgt * l;
}
else val += wgt * v[comp];
}
vol += wgt;
}
res = val/vol;
......@@ -4781,7 +4874,24 @@ void svg_draw(std::ostream & file)
//glTranslated((l+r)*0.5,(b+t)*0.5,(near+far)*0.5);
if( drawedges == 4 )
{
std::vector<face2gl> sorted_clip_boundary;
for(std::map<int,std::vector<HandleType> >::iterator it = material_faces.begin(); it != material_faces.end(); ++it)
{
for(std::vector<HandleType>::iterator jt = it->second.begin(); jt != it->second.end(); ++jt)
{
sorted_clip_boundary.push_back(DrawFace(Face(mesh,*jt)));
sorted_clip_boundary.back().shift(material_x[it->first],material_y[it->first],material_z[it->first]);
sorted_clip_boundary.back().compute_dist(campos);
sorted_clip_boundary.back().set_color(1,1,1,1);
}
}
face2gl::radix_sort_dist(sorted_clip_boundary);
//std::sort(sorted_clip_boundary.rbegin(),sorted_clip_boundary.rend());
svg_draw_faces(file,sorted_clip_boundary,modelview,projection,viewport);
}
else
{
if( oclipper )
......@@ -5183,6 +5293,58 @@ int main(int argc, char ** argv)
for(int k = was; k < orphans.size(); ++k)
std::cout << ElementTypeName(orphans[k]->GetElementType()) << ":" << orphans[k]->LocalID() << std::endl;
}
}
if( mesh->HaveTag("MATERIAL") )
{
is_material_defined = 1;
Tag mat = mesh->GetTag("MATERIAL");
for(Mesh::iteratorFace it = mesh->BeginFace(); it != mesh->EndFace(); ++it)
{
int m1 = -1, m2 = -1;
if( it->BackCell().isValid() ) m1 = it->BackCell()->Integer(mat);
if( it->FrontCell().isValid() ) m2 = it->FrontCell()->Integer(mat);
if( m1 != m2 )
{
if( m1 >= 0 ) material_faces[m1].push_back(it->GetHandle());
if( m2 >= 0 ) material_faces[m2].push_back(it->GetHandle());
}
}
std::map<int,double> material_v;
double gx = 0, gy = 0, gz = 0, gv = 0;
for(Mesh::iteratorCell it = mesh->BeginCell(); it != mesh->EndCell(); ++it)
{
double cnt[3], v = it->Volume();
it->Centroid(cnt);
int m = it->Integer(mat);
material_x[m] += cnt[0]*v;
material_y[m] += cnt[1]*v;
material_z[m] += cnt[2]*v;
material_v[m] += v;
gx += cnt[0]*v;
gy += cnt[1]*v;
gz += cnt[2]*v;
gv += v;
}
gx /= gv;
gy /= gv;
gz /= gv;
for(std::map<int,double>::iterator it = material_v.begin(); it != material_v.end(); ++it)
{
double & x = material_x[it->first];
double & y = material_y[it->first];
double & z = material_z[it->first];
x /= it->second;
y /= it->second;
z /= it->second;
double dx = x - gx;
double dy = y - gy;
double dz = z - gz;
x = dx * 0.65;
y = dy * 0.65;
z = dz * 0.65;
}
}
quatinit();
......
......@@ -468,11 +468,12 @@ namespace INMOST
template<typename typeB>
Matrix & operator =(Matrix<typeB> const & other)
{
if( n*m != other.n*other.m ) space.resize(other.n*other.m);
for(enumerator i = 0; i < other.n*other.m; ++i)
space[i] = get_value(other.space[i]);
n = other.n;
m = other.m;
if( Cols()*Rows() != other.Cols()*other.Rows() ) space.resize(other.Cols()*other.Rows());
for(enumerator i = 0; i < other.Rows(); ++i)
for(enumerator j = 0; j < other.Cols(); ++j)
assign((*this)(i,j),other(i,j));
n = other.Rows();
m = other.Cols();
return *this;
}
// i is in [0,n] - row index
......@@ -737,6 +738,8 @@ namespace INMOST
const Var * data() const {return space.data();}
enumerator Rows() const {return n;}
enumerator Cols() const {return m;}
enumerator & Rows() {return n;}
enumerator & Cols() {return m;}
void Print(INMOST_DATA_REAL_TYPE threshold = 1.0e-10) const
{
for(enumerator k = 0; k < n; ++k)
......@@ -1105,6 +1108,13 @@ namespace INMOST
}
return ret;
}
//change representation of the matrix into matrix of another size
void Repack(enumerator _n, enumerator _m)
{
assert(n*m==_n*_m);
n = _n;
m = _m;
}
};
typedef Matrix<INMOST_DATA_REAL_TYPE> rMatrix; //shortcut for real matrix
......
......@@ -1462,9 +1462,45 @@ namespace INMOST
throw NotImplemented;
}
};
template<class A>
class pow_const_expression : public shell_expression<pow_const_expression<A> >
template<class A, class B>
class atan2_expression : public shell_expression<atan2_expression<A,B> >
{
const A & left;
const B & right;
INMOST_DATA_REAL_TYPE value, ldmult, rdmult;
public:
atan2_expression(const shell_expression<A> & pleft, const shell_expression<B> & pright) : left(pleft), right(pright)
{
INMOST_DATA_REAL_TYPE lval = left.GetValue();
INMOST_DATA_REAL_TYPE rval = right.GetValue();
value = ::atan2(lval,rval);
ldmult = rval/(rval*rval+lval*lval);
rdmult = -lval/(rval*rval+lval*lval);
}
atan2_expression(const atan2_expression & other)
:left(other.left), right(other.right), value(other.value),
ldmult(other.ldmult), rdmult(other.rdmult) {}
__INLINE INMOST_DATA_REAL_TYPE GetValue() const { return value; }
__INLINE void GetJacobian(INMOST_DATA_REAL_TYPE mult, Sparse::RowMerger & r) const
{
left.GetJacobian(mult*ldmult,r);
right.GetJacobian(mult*rdmult,r);
}
__INLINE void GetJacobian(INMOST_DATA_REAL_TYPE mult, Sparse::Row & r) const
{
left.GetJacobian(mult*ldmult,r);
right.GetJacobian(mult*rdmult,r);
}
__INLINE void GetHessian(INMOST_DATA_REAL_TYPE multJ, Sparse::Row & J, INMOST_DATA_REAL_TYPE multH, Sparse::HessianRow & H) const
{
throw NotImplemented;
}
};
template<class A>
class pow_const_expression : public shell_expression<pow_const_expression<A> >
{
const A & left;
INMOST_DATA_REAL_TYPE value, ldmult;
......@@ -1824,18 +1860,25 @@ template<class A> __INLINE INMOST_DATA_REAL_TY
__INLINE void set_value(INMOST::multivar_expression_reference & Arg, const INMOST::multivar_expression & Val) {Arg.SetValue(Val.GetValue()); }
__INLINE void set_value(INMOST::multivar_expression_reference & Arg, const INMOST::multivar_expression_reference & Val) {Arg.SetValue(Val.GetValue()); }
__INLINE void assign(INMOST::var_expression & Arg, INMOST_DATA_REAL_TYPE Val) {Arg = Val;}
__INLINE void assign(INMOST::multivar_expression & Arg, INMOST_DATA_REAL_TYPE Val) {Arg = Val; }
__INLINE void assign(INMOST::multivar_expression_reference & Arg, INMOST_DATA_REAL_TYPE Val) {Arg = Val; }
__INLINE void assign(INMOST_DATA_REAL_TYPE & Arg, INMOST_DATA_REAL_TYPE Val) {Arg = Val;}
__INLINE void assign(INMOST_DATA_REAL_TYPE & Arg, const INMOST::var_expression & Val) {Arg = Val.GetValue();}
__INLINE void assign(INMOST_DATA_REAL_TYPE & Arg, const INMOST::multivar_expression & Val) {Arg = Val.GetValue();}
__INLINE void assign(INMOST_DATA_REAL_TYPE & Arg, const INMOST::multivar_expression_reference & Val) {Arg = Val.GetValue();}
__INLINE void assign(INMOST::multivar_expression & Arg, INMOST_DATA_REAL_TYPE Val) {Arg = Val; }
__INLINE void assign(INMOST::multivar_expression & Arg, const INMOST::var_expression & Val) {Arg = Val; }
__INLINE void assign(INMOST::multivar_expression & Arg, const INMOST::multivar_expression & Val) {Arg = Val; }
__INLINE void assign(INMOST::multivar_expression & Arg, const INMOST::multivar_expression_reference & Val) {Arg = Val; }
__INLINE void assign(INMOST::multivar_expression & Arg, const INMOST::hessian_multivar_expression & Val) {Arg = Val; }
__INLINE void assign(INMOST::multivar_expression_reference & Arg, INMOST_DATA_REAL_TYPE Val) {Arg = Val; }
__INLINE void assign(INMOST::multivar_expression_reference & Arg, const INMOST::var_expression & Val) {Arg = Val; }
__INLINE void assign(INMOST::multivar_expression_reference & Arg, const INMOST::multivar_expression & Val) {Arg = Val; }
__INLINE void assign(INMOST::multivar_expression_reference & Arg, const INMOST::multivar_expression_reference & Val) {Arg = Val; }
__INLINE void assign(INMOST::multivar_expression_reference & Arg, const INMOST::hessian_multivar_expression & Val) {Arg = Val; }
__INLINE void assign(INMOST::hessian_multivar_expression & Arg, INMOST_DATA_REAL_TYPE Val) {Arg = Val; }
__INLINE void assign(INMOST::hessian_multivar_expression & Arg, const INMOST::var_expression & Val) {Arg = Val; }
__INLINE void assign(INMOST::hessian_multivar_expression & Arg, const INMOST::multivar_expression & Val) {Arg = Val; }
__INLINE void assign(INMOST::hessian_multivar_expression & Arg, const INMOST::multivar_expression_reference & Val) {Arg = Val; }
__INLINE void assign(INMOST::hessian_multivar_expression & Arg, const INMOST::hessian_multivar_expression & Val) {Arg = Val; }
template<class A> __INLINE INMOST::soft_abs_expression<A> soft_fabs(INMOST::shell_expression<A> const & Arg, INMOST_DATA_REAL_TYPE tol) { return INMOST::soft_abs_expression<A>(Arg,tol); }
__INLINE INMOST_DATA_REAL_TYPE soft_fabs(INMOST_DATA_REAL_TYPE Arg, INMOST_DATA_REAL_TYPE tol) {return ::sqrt(Arg*Arg+tol*tol);}
template<class A> __INLINE INMOST::soft_sign_expression<A> soft_sign(INMOST::shell_expression<A> const & Arg, INMOST_DATA_REAL_TYPE tol) { return INMOST::soft_sign_expression<A>(Arg,tol); }
......@@ -1845,6 +1888,7 @@ template<class A, class B> __INLINE INMOST::division_expression<A,
template<class A, class B> __INLINE INMOST::addition_expression<A, B> operator+(INMOST::shell_expression<A> const & Left, INMOST::shell_expression<B> const & Right) { return INMOST::addition_expression<A, B> (Left, Right); }
template<class A, class B> __INLINE INMOST::subtraction_expression<A, B> operator-(INMOST::shell_expression<A> const & Left, INMOST::shell_expression<B> const & Right) { return INMOST::subtraction_expression<A, B> (Left, Right); }
template<class A, class B> __INLINE INMOST::pow_expression<A, B> pow(INMOST::shell_expression<A> const & Left, INMOST::shell_expression<B> const & Right) { return INMOST::pow_expression<A, B> (Left, Right); }
template<class A, class B> __INLINE INMOST::atan2_expression<A, B> atan2(INMOST::shell_expression<A> const & Left, INMOST::shell_expression<B> const & Right) { return INMOST::atan2_expression<A, B> (Left, Right); }
template<class A, class B> __INLINE INMOST::soft_max_expression<A, B> soft_max(INMOST::shell_expression<A> const & Left, INMOST::shell_expression<B> const & Right ,INMOST_DATA_REAL_TYPE tol) { return INMOST::soft_max_expression<A, B> (Left, Right,tol); }
__INLINE INMOST_DATA_REAL_TYPE soft_max(INMOST_DATA_REAL_TYPE Left, INMOST_DATA_REAL_TYPE Right, INMOST_DATA_REAL_TYPE tol) {return 0.5*(Left+Right+::sqrt((Left-Right)*(Left-Right)+tol*tol));}
template<class A, class B> __INLINE INMOST::soft_min_expression<A, B> soft_min(INMOST::shell_expression<A> const & Left, INMOST::shell_expression<B> const & Right ,INMOST_DATA_REAL_TYPE tol) { return INMOST::soft_min_expression<A, B> (Left, Right,tol); }
......
......@@ -1184,6 +1184,8 @@ namespace INMOST
}
else fout << " ";
}
else if( !t->isSparse(etype) ) fout << " { } ";
}
break;
case DATA_INTEGER:
......@@ -1215,6 +1217,7 @@ namespace INMOST
else fout << " ";
//fout << std::endl;
}
else if( !t->isSparse(etype) ) fout << " { } ";
}
break;
case DATA_BULK:
......@@ -1246,6 +1249,7 @@ namespace INMOST
else fout << " ";
//fout << std::endl;
}
else if( !t->isSparse(etype) ) fout << " { } ";
}
break;
case DATA_REFERENCE:
......@@ -1291,6 +1295,7 @@ namespace INMOST
else fout << " ";
//fout << std::endl;
}
else if( !t->isSparse(etype) ) fout << " { } ";
}
break;
case DATA_REMOTE_REFERENCE:
......@@ -1336,6 +1341,7 @@ namespace INMOST
else fout << " ";
//fout << std::endl;
}
else if( !t->isSparse(etype) ) fout << " { } ";
}
break;
#if defined(USE_AUTODIFF)
......@@ -1368,6 +1374,7 @@ namespace INMOST
else fout << " ";
//fout << std::endl;
}
else if( !t->isSparse(etype) ) fout << " { } ";
}
break;
#endif
......
......@@ -981,7 +981,15 @@ namespace INMOST
found = true;
break;
}
if( !found ) return false;
if( !found )
{
std::cout << "Not found connection from ";
std::cout << ElementTypeName(GetHandleElementType(hc[jt])) << ":" << GetHandleID(hc[jt]);
std::cout << " to ";
std::cout << ElementTypeName(GetElementType()) << ":" << LocalID();
std::cout << std::endl;
return false;
}
}
adj_type const & lc = mesh->LowConn(GetHandle());
for(adj_type::size_type jt = 0; jt < lc.size(); jt++) //iterate over lower adjacent
......@@ -994,7 +1002,15 @@ namespace INMOST
found = true;
break;
}
if( !found ) return false;
if( !found )
{
std::cout << "Not found connection from ";
std::cout << ElementTypeName(GetHandleElementType(lc[jt])) << ":" << GetHandleID(lc[jt]);
std::cout << " to ";
std::cout << ElementTypeName(GetElementType()) << ":" << LocalID();
std::cout << std::endl;
return false;
}
}
return true;
}
......@@ -1041,9 +1057,10 @@ namespace INMOST
bool Element::CheckConnectivity(Mesh * m)
{
bool check = true;
for(Mesh::iteratorElement it = m->BeginElement(CELL | FACE | EDGE | NODE); it != m->EndElement(); it++)
if( !it->CheckElementConnectivity() ) return false;
return true;
if( !it->CheckElementConnectivity() ) check = false;
return check;
}
......
......@@ -748,8 +748,9 @@ namespace INMOST
if( m->GetMarker(lc[k],rem) )
{
//all united edges should appear in consecutive order in deleted face
/*
adj_type::size_type sum = 0, j = k;
while( !m->GetMarker(lc[j],hm) && m->GetMarker(lc[j],rem) )
while( j < lc.size() && !m->GetMarker(lc[j],hm) && m->GetMarker(lc[j],rem) )
{
sum++; j++;
}
......@@ -758,6 +759,7 @@ namespace INMOST
doexit = true;
dothrow = true;
}
*/
insert_pos.push_back(k);
break;
}
......@@ -1042,15 +1044,43 @@ namespace INMOST
for(dynarray<HandleType,64>::size_type it = 0; it < faces.size(); ++it)
{
adj_type & lc = m->LowConn(faces[it]);
lc.insert(lc.begin()+insert_pos[it],ret.begin(),ret.end());
//check that that one of the nodes of privious edge match n[0],
//otherwise we have to insert in reverse
const adj_type & phc = m->LowConn(lc[(insert_pos[it]+lc.size()-1)%lc.size()]);
if( phc[0] == n[0] || phc[1] == n[0] )
lc.insert(lc.begin()+insert_pos[it],ret.begin(),ret.end());
else
lc.insert(lc.begin()+insert_pos[it],ret.rbegin(),ret.rend());
m->ComputeGeometricType(faces[it]);
m->RecomputeGeometricData(faces[it]);
//Face(m,faces[it]).FixEdgeOrder();
}
//inform edges that they are connected to faces
for(ElementArray<Edge>::iterator kt = ret.begin(); kt != ret.end(); ++kt)
{
adj_type & hc = m->HighConn(kt->GetHandle());
hc.insert(hc.end(),faces.begin(),faces.end());
}
for(dynarray<HandleType,128>::size_type it = 0; it < cells.size(); ++it)
{
adj_type & hc = m->HighConn(cells[it]); //cell nodes
hc.clear(); //have to recompute cell nodes
m->ComputeGeometricType(cells[it]);
ElementArray<Node> nn(m);
m->RestoreCellNodes(cells[it],nn);
hc.insert(hc.begin(),nn.begin(),nn.end());
m->RecomputeGeometricData(cells[it]);
//connect nodes to cells
for(ElementArray<Node>::size_type k = 0; k < nn.size(); k++)
{
adj_type & nlc = m->LowConn(nn[k].GetHandle()); //node cells
bool have_cell = false;
for(adj_type::iterator kt = nlc.begin(); kt != nlc.end() && !have_cell; ++kt)
if( *kt == cells[it] ) have_cell = true;
if( !have_cell )
nlc.push_back(cells[it]);
}
}
return ret;
}
......@@ -1069,7 +1099,6 @@ namespace INMOST
dynarray<HandleType,128> temp;
if( edges.empty() || face->GetMarker(del_protect) ) return ret;
MarkerType hm = m->HideMarker();
ElementArray<Edge>::size_type input_edges = edges.size();
dynarray<HandleType,2> cells;
adj_type & hc = m->HighConn(face->GetHandle());
......@@ -1078,13 +1107,34 @@ namespace INMOST
//assert(cells.size() == 2);