Smoothing.cpp
Go to the documentation of this file.00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024 #include "PreCompiled.h"
00025 #ifndef _PreComp_
00026 #endif
00027
00028 #include "Smoothing.h"
00029 #include "MeshKernel.h"
00030 #include "Algorithm.h"
00031 #include "Elements.h"
00032 #include "Iterator.h"
00033 #include "Approximation.h"
00034
00035
00036 using namespace MeshCore;
00037
00038
00039 AbstractSmoothing::AbstractSmoothing(MeshKernel& m) : kernel(m)
00040 {
00041 }
00042
00043 AbstractSmoothing::~AbstractSmoothing()
00044 {
00045 }
00046
00047 void AbstractSmoothing::initialize(Component comp, Continuity cont)
00048 {
00049 this->component = comp;
00050 this->continuity = cont;
00051 }
00052
00053 MeshSmoothing::MeshSmoothing(MeshKernel& m)
00054 : AbstractSmoothing(m)
00055 {
00056 }
00057
00058 MeshSmoothing::~MeshSmoothing()
00059 {
00060 }
00061
00062 void MeshSmoothing::Smooth(unsigned int iterations)
00063 {
00064 MeshCore::MeshPoint center;
00065 MeshCore::MeshPointArray PointArray = kernel.GetPoints();
00066
00067 MeshCore::MeshPointIterator v_it(kernel);
00068 MeshCore::MeshRefPointToPoints vv_it(kernel);
00069 MeshCore::MeshPointArray::_TConstIterator v_beg = kernel.GetPoints().begin();
00070
00071 for (unsigned int i=0; i<iterations; i++) {
00072 Base::Vector3f N, L;
00073 for (v_it.Begin(); v_it.More(); v_it.Next()) {
00074 MeshCore::PlaneFit pf;
00075 pf.AddPoint(*v_it);
00076 center = *v_it;
00077 const std::set<unsigned long>& cv = vv_it[v_it.Position()];
00078 if (cv.size() < 3)
00079 continue;
00080
00081 std::set<unsigned long>::const_iterator cv_it;
00082 for (cv_it = cv.begin(); cv_it !=cv.end(); ++cv_it) {
00083 pf.AddPoint(v_beg[*cv_it]);
00084 center += v_beg[*cv_it];
00085 }
00086
00087 float scale = 1.0f/((float)cv.size()+1.0f);
00088 center.Scale(scale,scale,scale);
00089
00090
00091 pf.Fit();
00092 N = pf.GetNormal();
00093 N.Normalize();
00094
00095
00096 L.Set(v_it->x - center.x, v_it->y - center.y, v_it->z - center.z);
00097 if (N*L < 0.0)
00098 N.Scale(-1.0, -1.0, -1.0);
00099
00100
00101 float d = std::min<float>((float)fabs(this->tolerance),(float)fabs(N*L));
00102 N.Scale(d,d,d);
00103
00104 PointArray[v_it.Position()].Set(v_it->x - N.x, v_it->y - N.y, v_it->z - N.z);
00105 }
00106
00107
00108 unsigned long count = kernel.CountPoints();
00109 for (unsigned long idx = 0; idx < count; idx++) {
00110 kernel.SetPoint(idx, PointArray[idx]);
00111 }
00112 }
00113 }
00114
00115 LaplaceSmoothing::LaplaceSmoothing(MeshKernel& m)
00116 : AbstractSmoothing(m), lambda(0.6307)
00117 {
00118 }
00119
00120 LaplaceSmoothing::~LaplaceSmoothing()
00121 {
00122 }
00123
00124 void LaplaceSmoothing::Umbrella(const MeshRefPointToPoints& vv_it,
00125 const MeshRefPointToFacets& vf_it, double stepsize)
00126 {
00127 const MeshCore::MeshPointArray& points = kernel.GetPoints();
00128 MeshCore::MeshPointArray::_TConstIterator v_it,
00129 v_beg = points.begin(), v_end = points.end();
00130
00131 unsigned long pos = 0;
00132 for (v_it = points.begin(); v_it != v_end; ++v_it,++pos) {
00133 const std::set<unsigned long>& cv = vv_it[pos];
00134 if (cv.size() < 3)
00135 continue;
00136 if (cv.size() != vf_it[pos].size()) {
00137
00138 continue;
00139 }
00140
00141 unsigned int n_count = cv.size();
00142 double w;
00143 w=1.0/double(n_count);
00144
00145 double delx=0.0,dely=0.0,delz=0.0;
00146 std::set<unsigned long>::const_iterator cv_it;
00147 for (cv_it = cv.begin(); cv_it !=cv.end(); ++cv_it) {
00148 delx += w*((v_beg[*cv_it]).x-v_it->x);
00149 dely += w*((v_beg[*cv_it]).y-v_it->y);
00150 delz += w*((v_beg[*cv_it]).z-v_it->z);
00151 }
00152
00153 float x = (float)(v_it->x+stepsize*delx);
00154 float y = (float)(v_it->y+stepsize*dely);
00155 float z = (float)(v_it->z+stepsize*delz);
00156 kernel.SetPoint(pos,x,y,z);
00157 }
00158 }
00159
00160 void LaplaceSmoothing::Smooth(unsigned int iterations)
00161 {
00162 MeshCore::MeshRefPointToPoints vv_it(kernel);
00163 MeshCore::MeshRefPointToFacets vf_it(kernel);
00164
00165 for (unsigned int i=0; i<iterations; i++) {
00166 Umbrella(vv_it, vf_it, lambda);
00167 }
00168 }
00169
00170 TaubinSmoothing::TaubinSmoothing(MeshKernel& m)
00171 : LaplaceSmoothing(m), micro(0.0424)
00172 {
00173 }
00174
00175 TaubinSmoothing::~TaubinSmoothing()
00176 {
00177 }
00178
00179 void TaubinSmoothing::Smooth(unsigned int iterations)
00180 {
00181 MeshCore::MeshPointArray::_TConstIterator v_it;
00182 MeshCore::MeshRefPointToPoints vv_it(kernel);
00183 MeshCore::MeshRefPointToFacets vf_it(kernel);
00184
00185
00186 iterations = (iterations+1)/2;
00187 for (unsigned int i=0; i<iterations; i++) {
00188 Umbrella(vv_it, vf_it, lambda);
00189 Umbrella(vv_it, vf_it, -(lambda+micro));
00190 }
00191 }