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
00026 #ifndef _PreComp_
00027 # include <sstream>
00028 # include <BRepAdaptor_Curve.hxx>
00029 # include <BRepAdaptor_Surface.hxx>
00030 # include <BRepBndLib.hxx>
00031 # include <BRepBuilderAPI_GTransform.hxx>
00032 # include <Bnd_Box.hxx>
00033 # include <BRepTools.hxx>
00034 # include <BRepTools_ShapeSet.hxx>
00035 # include <BRepBuilderAPI_Copy.hxx>
00036 # include <TopTools_HSequenceOfShape.hxx>
00037 # include <TopTools_MapOfShape.hxx>
00038 # include <TopoDS.hxx>
00039 # include <TopoDS_Iterator.hxx>
00040 # include <TopExp.hxx>
00041 # include <Standard_Failure.hxx>
00042 # include <gp_GTrsf.hxx>
00043 # include <gp_Trsf.hxx>
00044 #endif
00045
00046
00047 #include <strstream>
00048 #include <Base/Console.h>
00049 #include <Base/Writer.h>
00050 #include <Base/Reader.h>
00051 #include <Base/Exception.h>
00052 #include <Base/FileInfo.h>
00053 #include <Base/Stream.h>
00054 #include <App/DocumentObject.h>
00055
00056 #include "PropertyTopoShape.h"
00057 #include "TopoShapePy.h"
00058 #include "TopoShapeFacePy.h"
00059 #include "TopoShapeEdgePy.h"
00060 #include "TopoShapeWirePy.h"
00061 #include "TopoShapeVertexPy.h"
00062 #include "TopoShapeSolidPy.h"
00063 #include "TopoShapeShellPy.h"
00064 #include "TopoShapeCompSolidPy.h"
00065 #include "TopoShapeCompoundPy.h"
00066
00067 using namespace Part;
00068
00069 TYPESYSTEM_SOURCE(Part::PropertyPartShape , App::PropertyComplexGeoData);
00070
00071 PropertyPartShape::PropertyPartShape()
00072 {
00073 }
00074
00075 PropertyPartShape::~PropertyPartShape()
00076 {
00077 }
00078
00079 void PropertyPartShape::setValue(const TopoShape& sh)
00080 {
00081 aboutToSetValue();
00082 _Shape = sh;
00083 hasSetValue();
00084 }
00085
00086 void PropertyPartShape::setValue(const TopoDS_Shape& sh)
00087 {
00088 aboutToSetValue();
00089 _Shape._Shape = sh;
00090 hasSetValue();
00091 }
00092
00093 const TopoDS_Shape& PropertyPartShape::getValue(void)const
00094 {
00095 return _Shape._Shape;
00096 }
00097
00098 const TopoShape& PropertyPartShape::getShape() const
00099 {
00100 return this->_Shape;
00101 }
00102
00103 const Data::ComplexGeoData* PropertyPartShape::getComplexData() const
00104 {
00105 return &(this->_Shape);
00106 }
00107
00108 Base::BoundBox3d PropertyPartShape::getBoundingBox() const
00109 {
00110 Base::BoundBox3d box;
00111 if (_Shape._Shape.IsNull())
00112 return box;
00113 try {
00114
00115 Bnd_Box bounds;
00116 BRepBndLib::Add(_Shape._Shape, bounds);
00117 bounds.SetGap(0.0);
00118 Standard_Real xMin, yMin, zMin, xMax, yMax, zMax;
00119 bounds.Get(xMin, yMin, zMin, xMax, yMax, zMax);
00120
00121 box.MinX = xMin;
00122 box.MaxX = xMax;
00123 box.MinY = yMin;
00124 box.MaxY = yMax;
00125 box.MinZ = zMin;
00126 box.MaxZ = zMax;
00127 }
00128 catch (Standard_Failure) {
00129 }
00130
00131 return box;
00132 }
00133
00134 void PropertyPartShape::getFaces(std::vector<Base::Vector3d> &aPoints,
00135 std::vector<Data::ComplexGeoData::Facet> &aTopo,
00136 float accuracy, uint16_t flags) const
00137 {
00138 _Shape.getFaces(aPoints, aTopo, accuracy, flags);
00139 }
00140
00141 void PropertyPartShape::transformGeometry(const Base::Matrix4D &rclTrf)
00142 {
00143 aboutToSetValue();
00144 _Shape.transformGeometry(rclTrf);
00145 hasSetValue();
00146 }
00147
00148 PyObject *PropertyPartShape::getPyObject(void)
00149 {
00150 const TopoDS_Shape& sh = _Shape._Shape;
00151 if (sh.IsNull())
00152 return new TopoShapePy(new TopoShape(sh));
00153
00154 TopAbs_ShapeEnum type = sh.ShapeType();
00155 switch (type)
00156 {
00157 case TopAbs_COMPOUND:
00158 return new TopoShapeCompoundPy(new TopoShape(sh));
00159 case TopAbs_COMPSOLID:
00160 return new TopoShapeCompSolidPy(new TopoShape(sh));
00161 case TopAbs_SOLID:
00162 return new TopoShapeSolidPy(new TopoShape(sh));
00163 case TopAbs_SHELL:
00164 return new TopoShapeShellPy(new TopoShape(sh));
00165 case TopAbs_FACE:
00166 return new TopoShapeFacePy(new TopoShape(sh));
00167 case TopAbs_WIRE:
00168 return new TopoShapeWirePy(new TopoShape(sh));
00169 case TopAbs_EDGE:
00170 return new TopoShapeEdgePy(new TopoShape(sh));
00171 case TopAbs_VERTEX:
00172 return new TopoShapeVertexPy(new TopoShape(sh));
00173 case TopAbs_SHAPE:
00174 default:
00175 return new TopoShapePy(new TopoShape(sh));
00176 break;
00177 }
00178 }
00179
00180 void PropertyPartShape::setPyObject(PyObject *value)
00181 {
00182 if (PyObject_TypeCheck(value, &(TopoShapePy::Type))) {
00183 TopoShapePy *pcObject = static_cast<TopoShapePy*>(value);
00184 setValue(*pcObject->getTopoShapePtr());
00185 }
00186 else {
00187 std::string error = std::string("type must be 'Shape', not ");
00188 error += value->ob_type->tp_name;
00189 throw Py::TypeError(error);
00190 }
00191 }
00192
00193 App::Property *PropertyPartShape::Copy(void) const
00194 {
00195 PropertyPartShape *prop = new PropertyPartShape();
00196 prop->_Shape = this->_Shape;
00197 if (!_Shape._Shape.IsNull()) {
00198 BRepBuilderAPI_Copy copy(_Shape._Shape);
00199 prop->_Shape._Shape = copy.Shape();
00200 }
00201
00202 return prop;
00203 }
00204
00205 void PropertyPartShape::Paste(const App::Property &from)
00206 {
00207 aboutToSetValue();
00208 _Shape = dynamic_cast<const PropertyPartShape&>(from)._Shape;
00209 hasSetValue();
00210 }
00211
00212 unsigned int PropertyPartShape::getMemSize (void) const
00213 {
00214 return _Shape.getMemSize();
00215 }
00216
00217 void PropertyPartShape::Save (Base::Writer &writer) const
00218 {
00219 if(!writer.isForceXML()) {
00220
00221 writer.Stream() << writer.ind() << "<Part file=\""
00222 << writer.addFile("PartShape.brp", this)
00223 << "\"/>" << std::endl;
00224 }
00225 }
00226
00227 void PropertyPartShape::Restore(Base::XMLReader &reader)
00228 {
00229 reader.readElement("Part");
00230 std::string file (reader.getAttribute("file") );
00231
00232 if (!file.empty()) {
00233
00234 reader.addFile(file.c_str(),this);
00235 }
00236 }
00237
00238 void PropertyPartShape::SaveDocFile (Base::Writer &writer) const
00239 {
00240
00241
00242 if (_Shape._Shape.IsNull())
00243 return;
00244
00245
00246
00247
00248
00249
00250
00251 static Base::FileInfo fi(Base::FileInfo::getTempFileName());
00252
00253 if (!BRepTools::Write(_Shape._Shape,(const Standard_CString)fi.filePath().c_str())) {
00254
00255
00256
00257
00258 App::PropertyContainer* father = this->getContainer();
00259 if (father && father->isDerivedFrom(App::DocumentObject::getClassTypeId())) {
00260 App::DocumentObject* obj = static_cast<App::DocumentObject*>(father);
00261 Base::Console().Error("Shape of '%s' cannot be written to BRep file '%s'\n",
00262 obj->Label.getValue(),fi.filePath().c_str());
00263 }
00264 else {
00265 Base::Console().Error("Cannot save BRep file '%s'\n", fi.filePath().c_str());
00266 }
00267 }
00268
00269 Base::ifstream file(fi, std::ios::in | std::ios::binary);
00270 if (file){
00271 unsigned long ulSize = 0;
00272 std::streambuf* buf = file.rdbuf();
00273 if (buf) {
00274 unsigned long ulCurr;
00275 ulCurr = buf->pubseekoff(0, std::ios::cur, std::ios::in);
00276 ulSize = buf->pubseekoff(0, std::ios::end, std::ios::in);
00277 buf->pubseekoff(ulCurr, std::ios::beg, std::ios::in);
00278 }
00279
00280
00281 std::strstreambuf sbuf(ulSize);
00282 file >> &sbuf;
00283 writer.Stream() << &sbuf;
00284 }
00285
00286 file.close();
00287
00288 fi.deleteFile();
00289 }
00290
00291 void PropertyPartShape::RestoreDocFile(Base::Reader &reader)
00292 {
00293 BRep_Builder builder;
00294
00295
00296 Base::FileInfo fi(Base::FileInfo::getTempFileName());
00297
00298
00299 Base::ofstream file(fi, std::ios::out | std::ios::binary);
00300 unsigned long ulSize = 0;
00301 if (reader) {
00302 std::streambuf* buf = file.rdbuf();
00303 reader >> buf;
00304 file.flush();
00305 ulSize = buf->pubseekoff(0, std::ios::cur, std::ios::in);
00306 }
00307 file.close();
00308
00309
00310
00311 TopoDS_Shape shape;
00312 if (ulSize > 0) {
00313 if (!BRepTools::Read(shape, (const Standard_CString)fi.filePath().c_str(), builder)) {
00314
00315
00316
00317
00318 App::PropertyContainer* father = this->getContainer();
00319 if (father && father->isDerivedFrom(App::DocumentObject::getClassTypeId())) {
00320 App::DocumentObject* obj = static_cast<App::DocumentObject*>(father);
00321 Base::Console().Error("BRep file '%s' with shape of '%s' seems to be empty\n",
00322 fi.filePath().c_str(),obj->Label.getValue());
00323 }
00324 else {
00325 Base::Console().Warning("Loaded BRep file '%s' seems to be empty\n", fi.filePath().c_str());
00326 }
00327 }
00328 }
00329
00330
00331 fi.deleteFile();
00332
00333 setValue(shape);
00334 }
00335
00336
00337
00338 TYPESYSTEM_SOURCE(Part::PropertyFilletEdges , App::PropertyLists);
00339
00340 PropertyFilletEdges::PropertyFilletEdges()
00341 {
00342 }
00343
00344 PropertyFilletEdges::~PropertyFilletEdges()
00345 {
00346 }
00347
00348 void PropertyFilletEdges::setValue(int id, double r1, double r2)
00349 {
00350 aboutToSetValue();
00351 _lValueList.resize(1);
00352 _lValueList[0].edgeid = id;
00353 _lValueList[0].radius1 = r1;
00354 _lValueList[0].radius2 = r2;
00355 hasSetValue();
00356 }
00357
00358 void PropertyFilletEdges::setValues(const std::vector<FilletElement>& values)
00359 {
00360 aboutToSetValue();
00361 _lValueList = values;
00362 hasSetValue();
00363 }
00364
00365 PyObject *PropertyFilletEdges::getPyObject(void)
00366 {
00367 Py::List list(getSize());
00368 std::vector<FilletElement>::const_iterator it;
00369 int index = 0;
00370 for (it = _lValueList.begin(); it != _lValueList.end(); ++it) {
00371 Py::Tuple ent(3);
00372 ent.setItem(0, Py::Int(it->edgeid));
00373 ent.setItem(1, Py::Float(it->radius1));
00374 ent.setItem(2, Py::Float(it->radius2));
00375 list[index++] = ent;
00376 }
00377
00378 return Py::new_reference_to(list);
00379 }
00380
00381 void PropertyFilletEdges::setPyObject(PyObject *value)
00382 {
00383 Py::List list(value);
00384 std::vector<FilletElement> values;
00385 values.reserve(list.size());
00386 for (Py::List::iterator it = list.begin(); it != list.end(); ++it) {
00387 FilletElement fe;
00388 Py::Tuple ent(*it);
00389 fe.edgeid = (int)Py::Int(ent.getItem(0));
00390 fe.radius1 = (double)Py::Float(ent.getItem(1));
00391 fe.radius2 = (double)Py::Float(ent.getItem(2));
00392 values.push_back(fe);
00393 }
00394
00395 setValues(values);
00396 }
00397
00398 void PropertyFilletEdges::Save (Base::Writer &writer) const
00399 {
00400 if (!writer.isForceXML()) {
00401 writer.Stream() << writer.ind() << "<FilletEdges file=\"" << writer.addFile(getName(), this) << "\"/>" << std::endl;
00402 }
00403 }
00404
00405 void PropertyFilletEdges::Restore(Base::XMLReader &reader)
00406 {
00407 reader.readElement("FilletEdges");
00408 std::string file (reader.getAttribute("file") );
00409
00410 if (!file.empty()) {
00411
00412 reader.addFile(file.c_str(),this);
00413 }
00414 }
00415
00416 void PropertyFilletEdges::SaveDocFile (Base::Writer &writer) const
00417 {
00418 Base::OutputStream str(writer.Stream());
00419 uint32_t uCt = (uint32_t)getSize();
00420 str << uCt;
00421 for (std::vector<FilletElement>::const_iterator it = _lValueList.begin(); it != _lValueList.end(); ++it) {
00422 str << it->edgeid << it->radius1 << it->radius2;
00423 }
00424 }
00425
00426 void PropertyFilletEdges::RestoreDocFile(Base::Reader &reader)
00427 {
00428 Base::InputStream str(reader);
00429 uint32_t uCt=0;
00430 str >> uCt;
00431 std::vector<FilletElement> values(uCt);
00432 for (std::vector<FilletElement>::iterator it = values.begin(); it != values.end(); ++it) {
00433 str >> it->edgeid >> it->radius1 >> it->radius2;
00434 }
00435 setValues(values);
00436 }
00437
00438 App::Property *PropertyFilletEdges::Copy(void) const
00439 {
00440 PropertyFilletEdges *p= new PropertyFilletEdges();
00441 p->_lValueList = _lValueList;
00442 return p;
00443 }
00444
00445 void PropertyFilletEdges::Paste(const Property &from)
00446 {
00447 aboutToSetValue();
00448 _lValueList = dynamic_cast<const PropertyFilletEdges&>(from)._lValueList;
00449 hasSetValue();
00450 }