Properties.cpp

Go to the documentation of this file.
00001 /***************************************************************************
00002  *   Copyright (c) Juergen Riegel         <juergen.riegel@web.de>          *
00003  *                                                                         *
00004  *   This file is part of the FreeCAD CAx development system.              *
00005  *                                                                         *
00006  *   This library is free software; you can redistribute it and/or         *
00007  *   modify it under the terms of the GNU Library General Public           *
00008  *   License as published by the Free Software Foundation; either          *
00009  *   version 2 of the License, or (at your option) any later version.      *
00010  *                                                                         *
00011  *   This library  is distributed in the hope that it will be useful,      *
00012  *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
00013  *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
00014  *   GNU Library General Public License for more details.                  *
00015  *                                                                         *
00016  *   You should have received a copy of the GNU Library General Public     *
00017  *   License along with this library; see the file COPYING.LIB. If not,    *
00018  *   write to the Free Software Foundation, Inc., 59 Temple Place,         *
00019  *   Suite 330, Boston, MA  02111-1307, USA                                *
00020  *                                                                         *
00021  ***************************************************************************/
00022 
00023 
00024 #include "PreCompiled.h"
00025 #ifndef _PreComp_
00026 # include <cmath>
00027 # include <iostream>
00028 # include <algorithm>
00029 #endif
00030 
00031 #include <Base/Exception.h>
00032 #include <Base/Matrix.h>
00033 #include <Base/Persistence.h>
00034 #include <Base/Stream.h>
00035 #include <Base/Writer.h>
00036 
00037 #include "Points.h"
00038 #include "Properties.h"
00039 #include "PointsPy.h"
00040 
00041 using namespace Points;
00042 using namespace std;
00043 
00044 TYPESYSTEM_SOURCE(Points::PropertyGreyValue, App::PropertyFloat);
00045 TYPESYSTEM_SOURCE(Points::PropertyGreyValueList, App::PropertyFloatList);
00046 TYPESYSTEM_SOURCE(Points::PropertyNormalList, App::PropertyVectorList);
00047 TYPESYSTEM_SOURCE(Points::PropertyCurvatureList , App::PropertyLists);
00048 
00049 void PropertyGreyValueList::removeIndices( const std::vector<unsigned long>& uIndices )
00050 {
00051     // We need a sorted array
00052     std::vector<unsigned long> uSortedInds = uIndices;
00053     std::sort(uSortedInds.begin(), uSortedInds.end());
00054 
00055     const std::vector<float>& rValueList = getValues();
00056 
00057     assert( uSortedInds.size() <= rValueList.size() );
00058     if ( uSortedInds.size() > rValueList.size() )
00059         return;
00060 
00061     std::vector<float> remainValue;
00062     remainValue.reserve(rValueList.size() - uSortedInds.size());
00063 
00064     std::vector<unsigned long>::iterator pos = uSortedInds.begin();
00065     for ( std::vector<float>::const_iterator it = rValueList.begin(); it != rValueList.end(); ++it ) {
00066         unsigned long index = it - rValueList.begin();
00067         if (pos == uSortedInds.end())
00068             remainValue.push_back( *it );
00069         else if (index != *pos)
00070             remainValue.push_back( *it );
00071         else 
00072             pos++;
00073     }
00074 
00075     setValues(remainValue);
00076 }
00077 
00078 void PropertyNormalList::transform(const Base::Matrix4D &mat)
00079 {
00080     // A normal vector is only a direction with unit length, so we only need to rotate it
00081     // (no translations or scaling)
00082 
00083     // Extract scale factors (assumes an orthogonal rotation matrix)
00084     // Use the fact that the length of the row vectors of R are all equal to 1
00085     // And that scaling is applied after rotating
00086     double s[3];
00087     s[0] = sqrt(mat[0][0] * mat[0][0] + mat[0][1] * mat[0][1] + mat[0][2] * mat[0][2]);
00088     s[1] = sqrt(mat[1][0] * mat[1][0] + mat[1][1] * mat[1][1] + mat[1][2] * mat[1][2]);
00089     s[2] = sqrt(mat[2][0] * mat[2][0] + mat[2][1] * mat[2][1] + mat[2][2] * mat[2][2]);
00090 
00091     // Set up the rotation matrix: zero the translations and make the scale factors = 1
00092     Base::Matrix4D rot;
00093     rot.setToUnity();
00094     for (unsigned short i = 0; i < 3; i++) {
00095         for (unsigned short j = 0; j < 3; j++) {
00096             rot[i][j] = mat[i][j] / s[i];
00097         }
00098     }
00099 
00100     // Rotate the normal vectors
00101     for (int ii=0; ii<getSize(); ii++) {
00102         set1Value(ii, rot * operator[](ii));
00103     }
00104 }
00105 
00106 void PropertyNormalList::removeIndices( const std::vector<unsigned long>& uIndices )
00107 {
00108     // We need a sorted array
00109     std::vector<unsigned long> uSortedInds = uIndices;
00110     std::sort(uSortedInds.begin(), uSortedInds.end());
00111 
00112     const std::vector<Base::Vector3f>& rValueList = getValues();
00113 
00114     assert( uSortedInds.size() <= rValueList.size() );
00115     if ( uSortedInds.size() > rValueList.size() )
00116         return;
00117 
00118     std::vector<Base::Vector3f> remainValue;
00119     remainValue.reserve(rValueList.size() - uSortedInds.size());
00120 
00121     std::vector<unsigned long>::iterator pos = uSortedInds.begin();
00122     for ( std::vector<Base::Vector3f>::const_iterator it = rValueList.begin(); it != rValueList.end(); ++it ) {
00123         unsigned long index = it - rValueList.begin();
00124         if (pos == uSortedInds.end())
00125             remainValue.push_back( *it );
00126         else if (index != *pos)
00127             remainValue.push_back( *it );
00128         else 
00129             pos++;
00130     }
00131 
00132     setValues(remainValue);
00133 }
00134 
00135 PropertyCurvatureList::PropertyCurvatureList()
00136 {
00137 
00138 }
00139 
00140 PropertyCurvatureList::~PropertyCurvatureList()
00141 {
00142 
00143 }
00144 
00145 void PropertyCurvatureList::setValue(const CurvatureInfo& lValue)
00146 {
00147     aboutToSetValue();
00148     _lValueList.resize(1);
00149     _lValueList[0]=lValue;
00150     hasSetValue();
00151 }
00152 
00153 void PropertyCurvatureList::setValues(const std::vector<CurvatureInfo>& lValues)
00154 {
00155     aboutToSetValue();
00156     _lValueList=lValues;
00157     hasSetValue();
00158 }
00159 
00160 std::vector<float> PropertyCurvatureList::getCurvature( int mode ) const
00161 {
00162     const std::vector<Points::CurvatureInfo>& fCurvInfo = getValues();
00163     std::vector<float> fValues;
00164     fValues.reserve(fCurvInfo.size());
00165 
00166     // Mean curvature
00167     if (mode == MeanCurvature) {
00168         for (std::vector<Points::CurvatureInfo>::const_iterator it=fCurvInfo.begin();it!=fCurvInfo.end(); ++it) {
00169             fValues.push_back( 0.5f*(it->fMaxCurvature+it->fMinCurvature) );
00170         }
00171     }
00172     // Gaussian curvature
00173     else if (mode == GaussCurvature) {
00174         for (std::vector<Points::CurvatureInfo>::const_iterator it=fCurvInfo.begin();it!=fCurvInfo.end(); ++it) {
00175             fValues.push_back( it->fMaxCurvature * it->fMinCurvature );
00176         }
00177     }
00178     // Maximum curvature
00179     else if (mode == MaxCurvature) {
00180         for (std::vector<Points::CurvatureInfo>::const_iterator it=fCurvInfo.begin();it!=fCurvInfo.end(); ++it) {
00181             fValues.push_back( it->fMaxCurvature );
00182         }
00183     }
00184     // Minimum curvature
00185     else if (mode == MinCurvature) {
00186         for (std::vector<Points::CurvatureInfo>::const_iterator it=fCurvInfo.begin();it!=fCurvInfo.end(); ++it) {
00187             fValues.push_back( it->fMinCurvature );
00188         }
00189     }
00190     // Absolute curvature
00191     else if (mode == AbsCurvature) {
00192         for (std::vector<Points::CurvatureInfo>::const_iterator it=fCurvInfo.begin();it!=fCurvInfo.end(); ++it) {
00193             if (fabs(it->fMaxCurvature) > fabs(it->fMinCurvature))
00194                 fValues.push_back( it->fMaxCurvature );
00195             else
00196                 fValues.push_back( it->fMinCurvature );
00197         }
00198     }
00199 
00200     return fValues;
00201 }
00202 
00203 void PropertyCurvatureList::transform(const Base::Matrix4D &mat)
00204 {
00205     // The principal direction is only a vector with unit length, so we only need to rotate it
00206     // (no translations or scaling)
00207 
00208     // Extract scale factors (assumes an orthogonal rotation matrix)
00209     // Use the fact that the length of the row vectors of R are all equal to 1
00210     // And that scaling is applied after rotating
00211     double s[3];
00212     s[0] = sqrt(mat[0][0] * mat[0][0] + mat[0][1] * mat[0][1] + mat[0][2] * mat[0][2]);
00213     s[1] = sqrt(mat[1][0] * mat[1][0] + mat[1][1] * mat[1][1] + mat[1][2] * mat[1][2]);
00214     s[2] = sqrt(mat[2][0] * mat[2][0] + mat[2][1] * mat[2][1] + mat[2][2] * mat[2][2]);
00215 
00216     // Set up the rotation matrix: zero the translations and make the scale factors = 1
00217     Base::Matrix4D rot;
00218     rot.setToUnity();
00219     for (unsigned short i = 0; i < 3; i++) {
00220         for (unsigned short j = 0; j < 3; j++) {
00221             rot[i][j] = mat[i][j] / s[i];
00222         }
00223     }
00224 
00225     // Rotate the principal directions
00226     for (int ii=0; ii<getSize(); ii++) {
00227         CurvatureInfo ci = operator[](ii);
00228         ci.cMaxCurvDir = rot * ci.cMaxCurvDir;
00229         ci.cMinCurvDir = rot * ci.cMinCurvDir;
00230         set1Value(ii, ci);
00231     }
00232 }
00233 
00234 void PropertyCurvatureList::removeIndices( const std::vector<unsigned long>& uIndices )
00235 {
00236     // We need a sorted array
00237     std::vector<unsigned long> uSortedInds = uIndices;
00238     std::sort(uSortedInds.begin(), uSortedInds.end());
00239 
00240     assert( uSortedInds.size() <= _lValueList.size() );
00241     if ( uSortedInds.size() > _lValueList.size() )
00242         return;
00243 
00244     std::vector<CurvatureInfo> remainValue;
00245     remainValue.reserve(_lValueList.size() - uSortedInds.size());
00246 
00247     std::vector<unsigned long>::iterator pos = uSortedInds.begin();
00248     for ( std::vector<CurvatureInfo>::const_iterator it = _lValueList.begin(); it != _lValueList.end(); ++it ) {
00249         unsigned long index = it - _lValueList.begin();
00250         if (pos == uSortedInds.end())
00251             remainValue.push_back( *it );
00252         else if (index != *pos)
00253             remainValue.push_back( *it );
00254         else 
00255             pos++;
00256     }
00257 
00258     setValues(remainValue);
00259 }
00260 
00261 void PropertyCurvatureList::Save (Base::Writer &writer) const
00262 {
00263     if (!writer.isForceXML()) {
00264         writer.Stream() << writer.ind() << "<CurvatureList file=\"" << writer.addFile(getName(), this) << "\"/>" << std::endl;
00265     }
00266 }
00267 
00268 void PropertyCurvatureList::Restore(Base::XMLReader &reader)
00269 {
00270     reader.readElement("CurvatureList");
00271     std::string file (reader.getAttribute("file") );
00272 
00273     if (!file.empty()) {
00274         // initate a file read
00275         reader.addFile(file.c_str(),this);
00276     }
00277 }
00278 
00279 void PropertyCurvatureList::SaveDocFile (Base::Writer &writer) const
00280 {
00281     Base::OutputStream str(writer.Stream());
00282     uint32_t uCt = (uint32_t)getSize();
00283     str << uCt;
00284     if (uCt > 0)
00285     for (std::vector<CurvatureInfo>::const_iterator it = _lValueList.begin(); it != _lValueList.end(); ++it) {
00286         str << it->fMaxCurvature << it->fMinCurvature;
00287         str << it->cMaxCurvDir.x << it->cMaxCurvDir.y << it->cMaxCurvDir.z;
00288         str << it->cMinCurvDir.x << it->cMinCurvDir.y << it->cMinCurvDir.z;
00289     }
00290 }
00291 
00292 void PropertyCurvatureList::RestoreDocFile(Base::Reader &reader)
00293 {
00294     Base::InputStream str(reader);
00295     uint32_t uCt=0;
00296     str >> uCt;
00297     std::vector<CurvatureInfo> values(uCt);
00298     for (std::vector<CurvatureInfo>::iterator it = values.begin(); it != values.end(); ++it) {
00299         str >> it->fMaxCurvature >> it->fMinCurvature;
00300         str >> it->cMaxCurvDir.x >> it->cMaxCurvDir.y >> it->cMaxCurvDir.z;
00301         str >> it->cMinCurvDir.x >> it->cMinCurvDir.y >> it->cMinCurvDir.z;
00302     }
00303 
00304     setValues(values);
00305 }
00306 
00307 App::Property *PropertyCurvatureList::Copy(void) const 
00308 {
00309     PropertyCurvatureList* prop = new PropertyCurvatureList();
00310     prop->_lValueList = this->_lValueList;
00311     return prop;
00312 }
00313 
00314 void PropertyCurvatureList::Paste(const App::Property &from)
00315 {
00316     aboutToSetValue();
00317     const PropertyCurvatureList& prop = dynamic_cast<const PropertyCurvatureList&>(from);
00318     this->_lValueList = prop._lValueList;
00319     hasSetValue();
00320 }
00321 
00322 unsigned int PropertyCurvatureList::getMemSize (void) const
00323 {
00324     return sizeof(CurvatureInfo) * this->_lValueList.size();
00325 }

Generated on Wed Nov 23 19:00:30 2011 for FreeCAD by  doxygen 1.6.1