/*************************************************************************** * Copyright (c) 2007 * * Joachim Zettler * * Human Rezai * * * * This file is part of the FreeCAD CAx development system. * * * * This library is free software; you can redistribute it and/or * * modify it under the terms of the GNU Library General Public * * License as published by the Free Software Foundation; either * * version 2 of the License, or (at your option) any later version. * * * * This library is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU Library General Public License for more details. * * * * You should have received a copy of the GNU Library General Public * * License along with this library; see the file COPYING.LIB. If not, * * write to the Free Software Foundation, Inc., 59 Temple Place, * * Suite 330, Boston, MA 02111-1307, USA * * * ***************************************************************************/ #include "PreCompiled.h" #include "UniGridApprox.h" #include "best_fit.h" #include #include #include #include #include #include #include #include #include // ///*********BINDINGS********/ #include #include #include // using namespace boost::numeric::bindings; typedef ublas::matrix cm_t; typedef ublas::symmetric_adaptor adapt; UniGridApprox::UniGridApprox(const MeshCore::MeshKernel &mesh, double Tol) :m_Mesh(mesh),m_Tol(Tol),m_udeg(3),m_vdeg(3) { } UniGridApprox::~UniGridApprox() { } bool UniGridApprox::Perform(double TOL) { double maxErr; cout << "MeshOffset" << endl; MeshOffset(); cout << "SurfMeshParam" << endl; SurfMeshParam(); while (true) { cout << "CompKnots" << endl; CompKnots(uCP, vCP); cout << "MatComp" << endl; MatComp(uCP, vCP); BuildSurf(); cout << "Compute Error"; maxErr = CompMeshError(); if (maxErr == -1) throw Base::RuntimeError("CompError() couldn't project one point..."); cout << " -> " << maxErr << endl; if (maxErr <= TOL) break; else { if (uCP >= vCP) { uCP += 10; vCP += vCP*10/uCP; } else { vCP += 10; uCP += uCP*10/vCP; } } if ( (uCP > (n_x + m_udeg + 1)) || (vCP > (n_y + m_vdeg + 1)) ) break; m_Grid.clear(); m_Grid = m_GridCopy; } return true; } bool UniGridApprox::MeshOffset() { MeshCore::MeshPointIterator p_it(m_Mesh); //vorläufige Lösung bis CAD-Normalen verwendet werden können std::vector normals = best_fit::Comp_Normals(m_Mesh); double x_max=-(1e+10),y_max=-(1e+10),z_max=-(1e+10),x_min=1e+10,y_min=1e+10,st_x,st_y; int n = normals.size(); // führe verschiebung durch //for(int i=0; iz>z_max) z_max = p_it->z; if (p_it->x>x_max) x_max = p_it->x; if (p_it->xx; if (p_it->y>y_max) y_max = p_it->y; if (p_it->yy; } // gittergrößen bestimmung über die bounding-box n_x = int((x_max - x_min)/(y_max - y_min)*sqrt((x_max - x_min)*(y_max - y_min))); n_y = int((y_max - y_min)/(x_max - x_min)*sqrt((x_max - x_min)*(y_max - y_min))); st_x = (x_max - x_min)/n_x; st_y = (y_max - y_min)/n_y; uCP = n_x/10; vCP = n_y/10; m_Grid.resize(n_x+1); for (int i=0; i (u,v) , ( R x R ) -> ( [0,1] x [0,1] ) int n = m_Grid.size()-1; // anzahl der zu approximierenden punkte in x-richtung int m = m_Grid[0].size()-1; // anzahl der zu approximierenden punkte in y-richtung std::vector dist_x, dist_y; double sum,d; Base::Vector3f vlen; m_uParam.clear(); m_vParam.clear(); m_uParam.resize(n+1); m_vParam.resize(m+1); m_uParam[n] = 1.0; m_vParam[m] = 1.0; // berechne knotenvektor in u-richtung (entspricht x-richtung) for (int j=0; j Nu_full(r - 1, n + 1); ublas::matrix Nv_full(s - 1, m + 1); ublas::matrix Nu_left(r - 1, n - 1); ublas::matrix Nv_left(s - 1, m - 1); ublas::matrix Nu (n - 1, n - 1); ublas::matrix Nv (m - 1, m - 1); ublas::matrix bx (1, n - 1); ublas::matrix by (1, n - 1); ublas::matrix bz (1, n - 1); // mit null vorinitialisieren for (int i=0; i output(p+1); int ind; for (int i=1; i upiv(n - 1); // pivotelement atlas::lu_factor(Nu,upiv); // führt LU-Zerlegung durch std::vector vpiv(m - 1); atlas::lu_factor(Nv,vpiv); ublas::matrix uCP_x(n + 1, s + 1); ublas::matrix uCP_y(n + 1, s + 1); ublas::matrix uCP_z(n + 1, s + 1); CPx.resize(n + 1, m + 1); CPy.resize(n + 1, m + 1); CPz.resize(n + 1, m + 1); // mit null vorinitialisieren for (int i=0; i > Ru_x(s+1); std::vector< ublas::matrix > Ru_y(s+1); std::vector< ublas::matrix > Ru_z(s+1); for (int j=0; j > Rv_x(n+1); std::vector< ublas::matrix > Rv_y(n+1); std::vector< ublas::matrix > Rv_z(n+1); Base::Builder3D log,logo; for (int j=0; j Tmp = CPz; //glättung des kontrollpunktnetzes for (int i=1; i tmp) tmp = mG_err[i][j]; } } return tmp; } bool UniGridApprox::WriteMatrix(ublas::matrix M) { int row = M.size1(); int col = M.size2(); for (int i=0; i normals = best_fit::Comp_Normals(mesh); double tmp = 0.0, sqrdis; double errSum = 0.0; int c=0; m_err.clear(); m_err.resize(mesh.CountPoints(), 0.0); MeshCore::MeshFacetGrid aFacetGrid(m_Mesh); MeshCore::MeshAlgorithm malg(m_Mesh); MeshCore::MeshAlgorithm malg2(m_Mesh); MeshCore::MeshPointIterator p_it(mesh); Base::Vector3f projPoint, distVec, pnt; unsigned long facetIndex; for (p_it.Begin(); p_it.More(); p_it.Next()) { if (!malg.NearestFacetOnRay(*p_it, normals[p_it.Position()], aFacetGrid, projPoint, facetIndex)) // gridoptimiert { if (malg2.NearestFacetOnRay(*p_it, normals[p_it.Position()], projPoint, facetIndex)) { pnt.x = p_it->x; pnt.y = p_it->y; pnt.z = p_it->z; log3d.addSingleLine(pnt,projPoint); distVec = projPoint - pnt; sqrdis = distVec*distVec; } else { cout << "oops, "; continue; } } else { pnt.x = p_it->x; pnt.y = p_it->y; pnt.z = p_it->z; log3d.addSingleLine(pnt,projPoint); distVec = projPoint - pnt; sqrdis = distVec*distVec; } errSum += sqrt(sqrdis); ++c; if (sqrt(sqrdis) > tmp) { m_err[p_it.Position()] = sqrt(sqrdis); tmp = m_err[p_it.Position()]; } } log3d.saveToFile("c:/Error.iv"); return errSum/c; }