PyObject* GeometrySurfacePy::tangent(PyObject *args)
{
    Handle_Geom_Geometry g = getGeometryPtr()->handle();
    Handle_Geom_Surface s = Handle_Geom_Surface::DownCast(g);
    try {
        if (!s.IsNull()) {
            double u,v;
            if (!PyArg_ParseTuple(args, "dd", &u,&v))
                return 0;
            gp_Dir dir;
            Py::Tuple tuple(2);
            GeomLProp_SLProps prop(s,u,v,1,Precision::Confusion());
            if (prop.IsTangentUDefined()) {
                prop.TangentU(dir);
                tuple.setItem(0, Py::Vector(Base::Vector3d(dir.X(),dir.Y(),dir.Z())));
            }
            if (prop.IsTangentVDefined()) {
                prop.TangentV(dir);
                tuple.setItem(1, Py::Vector(Base::Vector3d(dir.X(),dir.Y(),dir.Z())));
            }

            return Py::new_reference_to(tuple);
        }
    }
    catch (Standard_Failure) {
        Handle_Standard_Failure e = Standard_Failure::Caught();
        PyErr_SetString(PartExceptionOCCError, e->GetMessageString());
        return 0;
    }

    PyErr_SetString(PartExceptionOCCError, "Geometry is not a surface");
    return 0;
}
PyObject* GeometrySurfacePy::parameter(PyObject *args)
{
    Handle_Geom_Surface surf = Handle_Geom_Surface
        ::DownCast(getGeometryPtr()->handle());
    try {
        if (!surf.IsNull()) {
            PyObject *p;
            double prec = Precision::Confusion();
            if (!PyArg_ParseTuple(args, "O!|d", &(Base::VectorPy::Type), &p, &prec))
                return 0;
            Base::Vector3d v = Py::Vector(p, false).toVector();
            gp_Pnt pnt(v.x,v.y,v.z);
            ShapeAnalysis_Surface as(surf);
            gp_Pnt2d uv = as.ValueOfUV(pnt, prec);
            Py::Tuple tuple(2);
            tuple.setItem(0, Py::Float(uv.X()));
            tuple.setItem(1, Py::Float(uv.Y()));
            return Py::new_reference_to(tuple);
        }
    }
    catch (Standard_Failure) {
        Handle_Standard_Failure e = Standard_Failure::Caught();
        PyErr_SetString(PartExceptionOCCError, e->GetMessageString());
        return 0;
    }

    PyErr_SetString(PartExceptionOCCError, "Geometry is not a surface");
    return 0;
}
PyObject* GeometrySurfacePy::toShape(PyObject *args)
{
    Handle_Geom_Geometry g = getGeometryPtr()->handle();
    Handle_Geom_Surface s = Handle_Geom_Surface::DownCast(g);
    try {
        if (!s.IsNull()) {
            double u1,u2,v1,v2;
            s->Bounds(u1,u2,v1,v2);
            if (!PyArg_ParseTuple(args, "|dddd", &u1,&u2,&v1,&v2))
                return 0;
            BRepBuilderAPI_MakeFace mkBuilder(s, u1, u2, v1, v2
#if OCC_VERSION_HEX >= 0x060502
              , Precision::Confusion()
#endif
            );
            TopoDS_Shape sh = mkBuilder.Shape();
            return new TopoShapeFacePy(new TopoShape(sh));
        }
    }
    catch (Standard_Failure) {
        Handle_Standard_Failure e = Standard_Failure::Caught();
        PyErr_SetString(PartExceptionOCCError, e->GetMessageString());
        return 0;
    }

    PyErr_SetString(PartExceptionOCCError, "Geometry is not a surface");
    return 0;
}
PyObject* GeometrySurfacePy::vIso(PyObject * args)
{
    double v;
    if (!PyArg_ParseTuple(args, "d", &v))
        return 0;

    try {
        Handle_Geom_Surface surf = Handle_Geom_Surface::DownCast
            (getGeometryPtr()->handle());
        Handle_Geom_Curve c = surf->VIso(v);
        if (c->IsKind(STANDARD_TYPE(Geom_Line))) {
            Handle_Geom_Line aLine = Handle_Geom_Line::DownCast(c);
            GeomLineSegment* line = new GeomLineSegment();
            Handle_Geom_TrimmedCurve this_curv = Handle_Geom_TrimmedCurve::DownCast
                (line->handle());
            Handle_Geom_Line this_line = Handle_Geom_Line::DownCast
                (this_curv->BasisCurve());
            this_line->SetLin(aLine->Lin());
            return new LinePy(line);
        }
        else {
            return Py::new_reference_to(makeGeometryCurvePy(c));
        }
    }
    catch (Standard_Failure) {
        Handle_Standard_Failure e = Standard_Failure::Caught();
        PyErr_SetString(PartExceptionOCCError, e->GetMessageString());
        return 0;
    }
}
PyObject* GeometrySurfacePy::intersect(PyObject *args)
{
    Handle_Geom_Surface surf = Handle_Geom_Surface::DownCast(getGeometryPtr()->handle());
    try {
        if (!surf.IsNull()) {
            PyObject *p;
            double prec = Precision::Confusion();

            try {
                if (PyArg_ParseTuple(args, "O!|d", &(Part::GeometrySurfacePy::Type), &p, &prec))
                    return intersectSS(args);
            } catch(...) {};
            PyErr_Clear();

            if (PyArg_ParseTuple(args, "O!|d", &(Part::GeometryCurvePy::Type), &p, &prec)) {
                GeometryCurvePy* curve = static_cast<GeometryCurvePy*>(p);
                PyObject* t = PyTuple_New(2);
                PyTuple_SetItem(t, 0, this);
                PyTuple_SetItem(t, 1, PyFloat_FromDouble(prec));
                return curve->intersectCS(t);
            } else {
                return 0;
            }
        }
    }
    catch (Standard_Failure) {
        Handle_Standard_Failure e = Standard_Failure::Caught();
        PyErr_SetString(PyExc_Exception, e->GetMessageString());
        return 0;
    }

    PyErr_SetString(PyExc_Exception, "intersect(): Geometry is not a surface");
    return 0;
}
PyObject* GeometrySurfacePy::isVClosed(PyObject * args)
{
    if (!PyArg_ParseTuple(args, ""))
        return 0;

    Handle_Geom_Surface surf = Handle_Geom_Surface::DownCast
        (getGeometryPtr()->handle());
    Standard_Boolean val = surf->IsVClosed();
    return PyBool_FromLong(val ? 1 : 0);
}
Esempio n. 7
0
gp_Vec normalToSurfaceAtUV(const Handle_Geom_Surface& surface, double u, double v)
{
  gp_Pnt point;
  gp_Vec d1u, d1v;
  surface->D1(u, v, point, d1u, d1v);
  return d1u ^ d1v;
}
PyObject* GeometrySurfacePy::bounds(PyObject * args)
{
    if (!PyArg_ParseTuple(args, ""))
        return 0;

    Handle_Geom_Surface surf = Handle_Geom_Surface
        ::DownCast(getGeometryPtr()->handle());
    Py::Tuple bound(4);
    Standard_Real u1,u2,v1,v2;
    surf->Bounds(u1,u2,v1,v2);
    bound.setItem(0,Py::Float(u1));
    bound.setItem(1,Py::Float(u2));
    bound.setItem(2,Py::Float(v1));
    bound.setItem(3,Py::Float(v2));
    return Py::new_reference_to(bound);
}
//================================================================
// Function : DrawSurface                           
// Purpose  : displays a given geometric surface in 3d viewer
//            (creates a finite face and displays it)
//================================================================
Handle_AIS_InteractiveObject OCCDemo_Presentation::drawSurface
                                  (const Handle_Geom_Surface& theSurface,
                                   const Quantity_Color& theColor,
                                   const Standard_Boolean toDisplay)
{
  Standard_Real u1, u2, v1, v2;
  theSurface->Bounds(u1,u2,v1,v2);
  fixParam(u1);
  fixParam(u2);
  fixParam(v1);
  fixParam(v2);

  Handle_AIS_Shape aGraphicSurface = 
    new AIS_Shape(BRepBuilderAPI_MakeFace (theSurface, u1, u2, v1, v2));

  getAISContext()->SetMaterial(aGraphicSurface, Graphic3d_NOM_PLASTIC, toDisplay);
  getAISContext()->SetColor(aGraphicSurface, theColor, toDisplay);
  if (toDisplay) {
    if (FitMode){
		getAISContext()->Display (aGraphicSurface, Standard_False);
		COCCDemoDoc::Fit();
	}
	else
		getAISContext()->Display (aGraphicSurface);
  }
  
  return aGraphicSurface;
}
Esempio n. 10
0
static Handle(Geom_Plane) getGeomPlane(const TopoDS_Face &faceIn)
{
  Handle_Geom_Plane planeSurfaceOut;
  Handle_Geom_Surface surface = BRep_Tool::Surface(faceIn);
  if (!surface.IsNull())
  {
    planeSurfaceOut = Handle(Geom_Plane)::DownCast(surface);
    if (planeSurfaceOut.IsNull())
    {
      Handle_Geom_RectangularTrimmedSurface trimmedSurface = Handle(Geom_RectangularTrimmedSurface)::DownCast(surface);
      if (!trimmedSurface.IsNull())
        planeSurfaceOut = Handle(Geom_Plane)::DownCast(trimmedSurface->BasisSurface());
    }
  }

  return planeSurfaceOut;
}
PyObject* GeometrySurfacePy::VPeriod(PyObject * args)
{
    if (!PyArg_ParseTuple(args, ""))
        return 0;

    try {
        Handle_Geom_Surface surf = Handle_Geom_Surface::DownCast
            (getGeometryPtr()->handle());
        Standard_Real val = surf->VPeriod();
        return PyFloat_FromDouble(val);
    }
    catch (Standard_Failure) {
        Handle_Standard_Failure e = Standard_Failure::Caught();
        PyErr_SetString(PartExceptionOCCError, e->GetMessageString());
        return 0;
    }
}
PyObject* GeometrySurfacePy::isVClosed(PyObject * args)
{
    if (!PyArg_ParseTuple(args, ""))
        return 0;

    Handle_Geom_Surface surf = Handle_Geom_Surface::DownCast
        (getGeometryPtr()->handle());
    Standard_Boolean val = surf->IsVClosed();
    if (val) {
        Py_INCREF(Py_True);
        return Py_True;
    }
    else {
        Py_INCREF(Py_False);
        return Py_False;
    }
}
int convert_to_ifc(const TopoDS_Face& f, IfcSchema::IfcFace*& face, bool advanced) {
	Handle_Geom_Surface surf = BRep_Tool::Surface(f);
	TopExp_Explorer exp(f, TopAbs_WIRE);
	IfcSchema::IfcFaceBound::list::ptr bounds(new IfcSchema::IfcFaceBound::list);
	int index = 0;
	for (; exp.More(); exp.Next(), ++index) {
		IfcSchema::IfcLoop* loop;
		if (!convert_to_ifc(TopoDS::Wire(exp.Current()), loop, advanced)) {
			return 0;
		}
		IfcSchema::IfcFaceBound* bnd;
		if (index == 0) {
			bnd = new IfcSchema::IfcFaceOuterBound(loop, true);
		} else {
			bnd = new IfcSchema::IfcFaceBound(loop, true);
		}
		bounds->push(bnd);
	}

	const bool is_planar = surf->DynamicType() == STANDARD_TYPE(Geom_Plane);

	if (!is_planar && !advanced) {
		return 0;
	}
	if (is_planar && !advanced) {
		face = new IfcSchema::IfcFace(bounds);
		return 1;
	} else {
#ifdef USE_IFC4
		IfcSchema::IfcSurface* surface;
		if (!convert_to_ifc(surf, surface, advanced)) {
			return 0;
		}
		face = new IfcSchema::IfcAdvancedFace(bounds, surface, f.Orientation() == TopAbs_FORWARD);
		return 1;
#else
		// No IfcAdvancedFace in Ifc2x3
		return 0;
#endif
	}
}
Esempio n. 14
0
PyObject* GeometryCurvePy::makeRuledSurface(PyObject *args)
{
    PyObject* curve;
    if (!PyArg_ParseTuple(args, "O!", &(Part::GeometryCurvePy::Type), &curve))
        return 0;

    try {
        Handle_Geom_Curve aCrv1 = Handle_Geom_Curve::DownCast(getGeometryPtr()->handle());
        GeometryCurvePy* c = static_cast<GeometryCurvePy*>(curve);
        Handle_Geom_Curve aCrv2 = Handle_Geom_Curve::DownCast(c->getGeometryPtr()->handle());
        Handle_Geom_Surface aSurf = GeomFill::Surface (aCrv1, aCrv2);
        if (aSurf.IsNull()) {
            PyErr_SetString(PartExceptionOCCError, "Failed to create ruled surface");
            return 0;
        }
        // check the result surface type
        if (aSurf->IsKind(STANDARD_TYPE(Geom_RectangularTrimmedSurface))) {
            Handle_Geom_RectangularTrimmedSurface aTSurf = 
                Handle_Geom_RectangularTrimmedSurface::DownCast(aSurf);
            return new RectangularTrimmedSurfacePy(new GeomTrimmedSurface(aTSurf));
        }
        else if (aSurf->IsKind(STANDARD_TYPE(Geom_BSplineSurface))) {
            Handle_Geom_BSplineSurface aBSurf = 
                Handle_Geom_BSplineSurface::DownCast(aSurf);
            return new BSplineSurfacePy(new GeomBSplineSurface(aBSurf));
        }
        else {
            PyErr_Format(PyExc_NotImplementedError, "Ruled surface is of type '%s'",
                aSurf->DynamicType()->Name());
            return 0;
        }
    }
    catch (Standard_Failure) {
        Handle_Standard_Failure e = Standard_Failure::Caught();
        PyErr_SetString(PartExceptionOCCError, e->GetMessageString());
        return 0;
    }

    PyErr_SetString(PartExceptionOCCError, "Geometry is not a curve");
    return 0;
}
PyObject* GeometrySurfacePy::value(PyObject *args)
{
    Handle_Geom_Geometry g = getGeometryPtr()->handle();
    Handle_Geom_Surface s = Handle_Geom_Surface::DownCast(g);
    try {
        if (!s.IsNull()) {
            double u,v;
            if (!PyArg_ParseTuple(args, "dd", &u,&v))
                return 0;
            gp_Pnt p = s->Value(u,v);
            return new Base::VectorPy(Base::Vector3d(p.X(),p.Y(),p.Z()));
        }
    }
    catch (Standard_Failure) {
        Handle_Standard_Failure e = Standard_Failure::Caught();
        PyErr_SetString(PartExceptionOCCError, e->GetMessageString());
        return 0;
    }

    PyErr_SetString(PartExceptionOCCError, "Geometry is not a surface");
    return 0;
}
Esempio n. 16
0
// constructor method
int TopoShapeFacePy::PyInit(PyObject* args, PyObject* /*kwd*/)
{
    PyObject *pW;
    if (PyArg_ParseTuple(args, "O!", &(Part::TopoShapePy::Type), &pW)) {
        try {
            const TopoDS_Shape& sh = static_cast<Part::TopoShapePy*>(pW)->getTopoShapePtr()->_Shape;
            if (sh.IsNull()) {
                PyErr_SetString(PartExceptionOCCError, "cannot create face out of empty wire");
                return -1;
            }

            if (sh.ShapeType() == TopAbs_WIRE) {
                BRepBuilderAPI_MakeFace mkFace(TopoDS::Wire(sh));
                if (!mkFace.IsDone()) {
                    PyErr_SetString(PartExceptionOCCError, "Failed to create face from wire");
                    return -1;
                }
                getTopoShapePtr()->_Shape = mkFace.Face();
                return 0;
            }
            else if (sh.ShapeType() == TopAbs_FACE) {
                getTopoShapePtr()->_Shape = sh;
                return 0;
            }
        }
        catch (Standard_Failure) {
            Handle_Standard_Failure e = Standard_Failure::Caught();
            PyErr_SetString(PartExceptionOCCError, e->GetMessageString());
            return -1;
        }
    }

    PyErr_Clear();
    PyObject *surf, *bound=0;
    if (PyArg_ParseTuple(args, "O!|O!", &(GeometryPy::Type), &surf, &(PyList_Type), &bound)) {
        try {
            Handle_Geom_Surface S = Handle_Geom_Surface::DownCast
                (static_cast<GeometryPy*>(surf)->getGeometryPtr()->handle());
            if (S.IsNull()) {
                PyErr_SetString(PyExc_TypeError, "geometry is not a valid surface");
                return -1;
            }

            BRepBuilderAPI_MakeFace mkFace(S
#if OCC_VERSION_HEX >= 0x060502
              , Precision::Confusion()
#endif
            );
            if (bound) {
                Py::List list(bound);
                for (Py::List::iterator it = list.begin(); it != list.end(); ++it) {
                    PyObject* item = (*it).ptr();
                    if (PyObject_TypeCheck(item, &(Part::TopoShapePy::Type))) {
                        const TopoDS_Shape& sh = static_cast<Part::TopoShapePy*>(item)->getTopoShapePtr()->_Shape;
                        if (sh.ShapeType() == TopAbs_WIRE)
                            mkFace.Add(TopoDS::Wire(sh));
                        else {
                            PyErr_SetString(PyExc_TypeError, "shape is not a wire");
                            return -1;
                        }
                    }
                    else {
                        PyErr_SetString(PyExc_TypeError, "item is not a shape");
                        return -1;
                    }
                }
            }

            getTopoShapePtr()->_Shape = mkFace.Face();
            return 0;
        }
        catch (Standard_Failure) {
            Handle_Standard_Failure e = Standard_Failure::Caught();
            PyErr_SetString(PartExceptionOCCError, e->GetMessageString());
            return -1;
        }
    }

    PyErr_Clear();
    if (PyArg_ParseTuple(args, "O!", &(PyList_Type), &bound)) {
        try {
            std::vector<TopoDS_Wire> wires;
            Py::List list(bound);
            for (Py::List::iterator it = list.begin(); it != list.end(); ++it) {
                PyObject* item = (*it).ptr();
                if (PyObject_TypeCheck(item, &(Part::TopoShapePy::Type))) {
                    const TopoDS_Shape& sh = static_cast<Part::TopoShapePy*>(item)->getTopoShapePtr()->_Shape;
                    if (sh.ShapeType() == TopAbs_WIRE)
                        wires.push_back(TopoDS::Wire(sh));
                    else
                        Standard_Failure::Raise("shape is not a wire");
                }
                else
                    Standard_Failure::Raise("shape is not a wire");
            }

            if (!wires.empty()) {
                BRepBuilderAPI_MakeFace mkFace(wires.front());
                if (!mkFace.IsDone()) {
                    switch (mkFace.Error()) {
                    case BRepBuilderAPI_NoFace:
                        Standard_Failure::Raise("No face");
                        break;
                    case BRepBuilderAPI_NotPlanar:
                        Standard_Failure::Raise("Not planar");
                        break;
                    case BRepBuilderAPI_CurveProjectionFailed:
                        Standard_Failure::Raise("Curve projection failed");
                        break;
                    case BRepBuilderAPI_ParametersOutOfRange:
                        Standard_Failure::Raise("Parameters out of range");
                        break;
#if OCC_VERSION_HEX < 0x060500
                    case BRepBuilderAPI_SurfaceNotC2:
                        Standard_Failure::Raise("Surface not C2");
                        break;
#endif
                    default:
                        Standard_Failure::Raise("Unknown failure");
                        break;
                    }
                }
                for (std::vector<TopoDS_Wire>::iterator it = wires.begin()+1; it != wires.end(); ++it)
                    mkFace.Add(*it);
                getTopoShapePtr()->_Shape = mkFace.Face();
                return 0;
            }
            else {
                Standard_Failure::Raise("no wires in list");
            }
        }
        catch (Standard_Failure) {
            Handle_Standard_Failure e = Standard_Failure::Caught();
            PyErr_SetString(PartExceptionOCCError, e->GetMessageString());
            return -1;
        }
    }

    PyErr_SetString(PartExceptionOCCError, "wire or list of wires expected");
    return -1;
}
int convert_to_ifc(const Handle_Geom_Surface& s, IfcSchema::IfcSurface*& surface, bool advanced) {
	if (s->DynamicType() == STANDARD_TYPE(Geom_Plane)) {
		Handle_Geom_Plane plane = Handle_Geom_Plane::DownCast(s);
		IfcSchema::IfcAxis2Placement3D* place;
		/// @todo: Note that the Ax3 is converted to an Ax2 here
		if (!convert_to_ifc(plane->Position().Ax2(), place, advanced)) {
			return 0;
		}
		surface = new IfcSchema::IfcPlane(place);
		return 1;
	}
#ifdef USE_IFC4
	else if (s->DynamicType() == STANDARD_TYPE(Geom_CylindricalSurface)) {
		Handle_Geom_CylindricalSurface cyl = Handle_Geom_CylindricalSurface::DownCast(s);
		IfcSchema::IfcAxis2Placement3D* place;
		/// @todo: Note that the Ax3 is converted to an Ax2 here
		if (!convert_to_ifc(cyl->Position().Ax2(), place, advanced)) {
			return 0;
		}
		surface = new IfcSchema::IfcCylindricalSurface(place, cyl->Radius());
		return 1;
	} else if (s->DynamicType() == STANDARD_TYPE(Geom_BSplineSurface)) {
		typedef IfcTemplatedEntityListList<IfcSchema::IfcCartesianPoint> points_t;

		Handle_Geom_BSplineSurface bspline = Handle_Geom_BSplineSurface::DownCast(s);
		points_t::ptr points(new points_t);

		TColgp_Array2OfPnt poles(1, bspline->NbUPoles(), 1, bspline->NbVPoles());
		bspline->Poles(poles);
		for (int i = 1; i <= bspline->NbUPoles(); ++i) {
			std::vector<IfcSchema::IfcCartesianPoint*> ps;
			ps.reserve(bspline->NbVPoles());
			for (int j = 1; j <= bspline->NbVPoles(); ++j) {
				IfcSchema::IfcCartesianPoint* p;
				if (!convert_to_ifc(poles.Value(i, j), p, advanced)) {
					return 0;
				}
				ps.push_back(p);
			}
			points->push(ps);
		}

		IfcSchema::IfcKnotType::IfcKnotType knot_spec_u = opencascade_knotspec_to_ifc(bspline->UKnotDistribution());
		IfcSchema::IfcKnotType::IfcKnotType knot_spec_v = opencascade_knotspec_to_ifc(bspline->VKnotDistribution());

		if (knot_spec_u != knot_spec_v) {
			knot_spec_u = IfcSchema::IfcKnotType::IfcKnotType_UNSPECIFIED;
		}

		std::vector<int> umults;
		std::vector<int> vmults;
		std::vector<double> uknots;
		std::vector<double> vknots;
		std::vector< std::vector<double> > weights;

		TColStd_Array1OfInteger bspline_umults(1, bspline->NbUKnots());
		TColStd_Array1OfInteger bspline_vmults(1, bspline->NbVKnots());
		TColStd_Array1OfReal bspline_uknots(1, bspline->NbUKnots());
		TColStd_Array1OfReal bspline_vknots(1, bspline->NbVKnots());
		TColStd_Array2OfReal bspline_weights(1, bspline->NbUPoles(), 1, bspline->NbVPoles());

		bspline->UMultiplicities(bspline_umults);
		bspline->VMultiplicities(bspline_vmults);
		bspline->UKnots(bspline_uknots);
		bspline->VKnots(bspline_vknots);
		bspline->Weights(bspline_weights);

		opencascade_array_to_vector(bspline_umults, umults);
		opencascade_array_to_vector(bspline_vmults, vmults);
		opencascade_array_to_vector(bspline_uknots, uknots);
		opencascade_array_to_vector(bspline_vknots, vknots);
		opencascade_array_to_vector2(bspline_weights, weights);

		bool rational = false;
		for (std::vector< std::vector<double> >::const_iterator it = weights.begin(); it != weights.end(); ++it) {
			for (std::vector<double>::const_iterator jt = it->begin(); jt != it->end(); ++jt) {
				if ((*jt) != 1.) {
					rational = true;
					break;
				}
			}
		}

		if (rational) {
			surface = new IfcSchema::IfcRationalBSplineSurfaceWithKnots(
				bspline->UDegree(),
				bspline->VDegree(),
				points,
				IfcSchema::IfcBSplineSurfaceForm::IfcBSplineSurfaceForm_UNSPECIFIED,
				bspline->IsUClosed(),
				bspline->IsVClosed(),
				false,
				umults,
				vmults,
				uknots,
				vknots,
				knot_spec_u,
				weights
				);
		} else {
			surface = new IfcSchema::IfcBSplineSurfaceWithKnots(
				bspline->UDegree(),
				bspline->VDegree(),
				points,
				IfcSchema::IfcBSplineSurfaceForm::IfcBSplineSurfaceForm_UNSPECIFIED,
				bspline->IsUClosed(),
				bspline->IsVClosed(),
				false,
				umults,
				vmults,
				uknots,
				vknots,
				knot_spec_u
				);
		}

		return 1;
	}
#endif
	return 0;
}
// constructor method
int TopoShapeFacePy::PyInit(PyObject* args, PyObject* /*kwd*/)
{
    PyObject *pW;
    if (PyArg_ParseTuple(args, "O!", &(Part::TopoShapePy::Type), &pW)) {
        try {
            const TopoDS_Shape& sh = static_cast<Part::TopoShapePy*>(pW)->getTopoShapePtr()->getShape();
            if (sh.IsNull()) {
                PyErr_SetString(PartExceptionOCCError, "cannot create face out of empty wire");
                return -1;
            }

            if (sh.ShapeType() == TopAbs_WIRE) {
                BRepBuilderAPI_MakeFace mkFace(TopoDS::Wire(sh));
                if (!mkFace.IsDone()) {
                    PyErr_SetString(PartExceptionOCCError, "Failed to create face from wire");
                    return -1;
                }
                getTopoShapePtr()->setShape(mkFace.Face());
                return 0;
            }
            else if (sh.ShapeType() == TopAbs_FACE) {
                getTopoShapePtr()->setShape(sh);
                return 0;
            }
        }
        catch (Standard_Failure) {
            Handle_Standard_Failure e = Standard_Failure::Caught();
            PyErr_SetString(PartExceptionOCCError, e->GetMessageString());
            return -1;
        }
    }

    PyErr_Clear();
    PyObject *surf, *bound=0;
    if (PyArg_ParseTuple(args, "O!|O!", &(GeometryPy::Type), &surf, &(PyList_Type), &bound)) {
        try {
            Handle_Geom_Surface S = Handle_Geom_Surface::DownCast
                (static_cast<GeometryPy*>(surf)->getGeometryPtr()->handle());
            if (S.IsNull()) {
                PyErr_SetString(PyExc_TypeError, "geometry is not a valid surface");
                return -1;
            }

            BRepBuilderAPI_MakeFace mkFace(S
#if OCC_VERSION_HEX >= 0x060502
              , Precision::Confusion()
#endif
            );
            if (bound) {
                Py::List list(bound);
                for (Py::List::iterator it = list.begin(); it != list.end(); ++it) {
                    PyObject* item = (*it).ptr();
                    if (PyObject_TypeCheck(item, &(Part::TopoShapePy::Type))) {
                        const TopoDS_Shape& sh = static_cast<Part::TopoShapePy*>(item)->getTopoShapePtr()->getShape();
                        if (sh.ShapeType() == TopAbs_WIRE)
                            mkFace.Add(TopoDS::Wire(sh));
                        else {
                            PyErr_SetString(PyExc_TypeError, "shape is not a wire");
                            return -1;
                        }
                    }
                    else {
                        PyErr_SetString(PyExc_TypeError, "item is not a shape");
                        return -1;
                    }
                }
            }

            getTopoShapePtr()->setShape(mkFace.Face());
            return 0;
        }
        catch (Standard_Failure) {
            Handle_Standard_Failure e = Standard_Failure::Caught();
            PyErr_SetString(PartExceptionOCCError, e->GetMessageString());
            return -1;
        }
    }

    PyErr_Clear();
    if (PyArg_ParseTuple(args, "O!", &(PyList_Type), &bound)) {
        try {
            std::vector<TopoDS_Wire> wires;
            Py::List list(bound);
            for (Py::List::iterator it = list.begin(); it != list.end(); ++it) {
                PyObject* item = (*it).ptr();
                if (PyObject_TypeCheck(item, &(Part::TopoShapePy::Type))) {
                    const TopoDS_Shape& sh = static_cast<Part::TopoShapePy*>(item)->getTopoShapePtr()->getShape();
                    if (sh.ShapeType() == TopAbs_WIRE)
                        wires.push_back(TopoDS::Wire(sh));
                    else
                        Standard_Failure::Raise("shape is not a wire");
                }
                else
                    Standard_Failure::Raise("shape is not a wire");
            }

            if (!wires.empty()) {
                BRepBuilderAPI_MakeFace mkFace(wires.front());
                if (!mkFace.IsDone()) {
                    switch (mkFace.Error()) {
                    case BRepBuilderAPI_NoFace:
                        Standard_Failure::Raise("No face");
                        break;
                    case BRepBuilderAPI_NotPlanar:
                        Standard_Failure::Raise("Not planar");
                        break;
                    case BRepBuilderAPI_CurveProjectionFailed:
                        Standard_Failure::Raise("Curve projection failed");
                        break;
                    case BRepBuilderAPI_ParametersOutOfRange:
                        Standard_Failure::Raise("Parameters out of range");
                        break;
#if OCC_VERSION_HEX < 0x060500
                    case BRepBuilderAPI_SurfaceNotC2:
                        Standard_Failure::Raise("Surface not C2");
                        break;
#endif
                    default:
                        Standard_Failure::Raise("Unknown failure");
                        break;
                    }
                }
                for (std::vector<TopoDS_Wire>::iterator it = wires.begin()+1; it != wires.end(); ++it)
                    mkFace.Add(*it);
                getTopoShapePtr()->setShape(mkFace.Face());
                return 0;
            }
            else {
                Standard_Failure::Raise("no wires in list");
            }
        }
        catch (Standard_Failure) {
            Handle_Standard_Failure e = Standard_Failure::Caught();
            PyErr_SetString(PartExceptionOCCError, e->GetMessageString());
            return -1;
        }
    }

    char* className = 0;
    PyObject* pcPyShapeOrList = nullptr;
    PyErr_Clear();
    if (PyArg_ParseTuple(args, "Os", &pcPyShapeOrList, &className)) {
        try {
            std::unique_ptr<FaceMaker> fm = Part::FaceMaker::ConstructFromType(className);

            //dump all supplied shapes to facemaker, no matter what type (let facemaker decide).
            if (PySequence_Check(pcPyShapeOrList)){
                Py::Sequence list(pcPyShapeOrList);
                for (Py::Sequence::iterator it = list.begin(); it != list.end(); ++it) {
                    PyObject* item = (*it).ptr();
                    if (PyObject_TypeCheck(item, &(Part::TopoShapePy::Type))) {
                        const TopoDS_Shape& sh = static_cast<Part::TopoShapePy*>(item)->getTopoShapePtr()->getShape();
                        fm->addShape(sh);
                    } else {
                        PyErr_SetString(PyExc_TypeError, "Object is not a shape.");
                        return -1;
                    }
                }
            } else if (PyObject_TypeCheck(pcPyShapeOrList, &(Part::TopoShapePy::Type))) {
                const TopoDS_Shape& sh = static_cast<Part::TopoShapePy*>(pcPyShapeOrList)->getTopoShapePtr()->getShape();
                if (sh.IsNull())
                    throw Base::Exception("Shape is null!");
                if (sh.ShapeType() == TopAbs_COMPOUND)
                    fm->useCompound(TopoDS::Compound(sh));
                else
                    fm->addShape(sh);
            } else {
                PyErr_SetString(PyExc_TypeError, "First argument is neither a shape nor list of shapes.");
                return -1;
            }

            fm->Build();

            getTopoShapePtr()->setShape(fm->Face());
            return 0;
        } catch (Base::Exception &e){
            PyErr_SetString(Base::BaseExceptionFreeCADError, e.what());
            return -1;
        } catch (Standard_Failure){
            Handle_Standard_Failure e = Standard_Failure::Caught();
            PyErr_SetString(PartExceptionOCCError, e->GetMessageString());
            return -1;
        }
    }

    PyErr_SetString(PartExceptionOCCError,
      "Argument list signature is incorrect.\n\nSupported signatures:\n"
      "(face)\n"
      "(wire)\n"
      "(list_of_wires)\n"
      "(wire, facemaker_class_name)\n"
      "(list_of_wires, facemaker_class_name)\n"
      "(surface, list_of_wires)\n"
                    );
    return -1;
}
// constructor method
int PlateSurfacePy::PyInit(PyObject* args, PyObject* kwds)
{
    static char* kwds_Parameter[] = {"Surface","Points","Curves","Degree",
        "NbPtsOnCur","NbIter","Tol2d","Tol3d","TolAng","TolCurv","Anisotropie",NULL};

    PyObject* surface = 0;
    PyObject* points = 0;
    PyObject* curves = 0;
    int Degree = 3;
    int NbPtsOnCur = 10;
    int NbIter = 3;
    double Tol2d = 0.00001;
    double Tol3d = 0.0001;
    double TolAng = 0.01;
    double TolCurv = 0.1;
    PyObject* Anisotropie = Py_False;

    if (!PyArg_ParseTupleAndKeywords(args, kwds, "|O!OOiiiddddO!", kwds_Parameter,
        &(GeometryPy::Type), &surface, &points, &curves,
        &Degree, &NbPtsOnCur, &NbIter, &Tol2d, &Tol3d, &TolAng, &TolCurv,
        &PyBool_Type,&Anisotropie))
        return -1;

    if (!surface && !points && !curves) {
        PyErr_SetString(PyExc_ValueError, "set points or curves as constraints");
        return -1;
    }

    Handle_Geom_Surface surf;
    if (surface) {
        GeometryPy* pcGeo = static_cast<GeometryPy*>(surface);
        surf = Handle_Geom_Surface::DownCast
            (pcGeo->getGeometryPtr()->handle());
        if (surf.IsNull()) {
            PyErr_SetString(PyExc_TypeError, "geometry is not a surface");
            return -1;
        }
    }

    try {
        GeomPlate_BuildPlateSurface buildPlate(Degree, NbPtsOnCur, NbIter, Tol2d, Tol3d, TolAng, TolCurv,
            PyObject_IsTrue(Anisotropie) ? Standard_True : Standard_False);
        if (!surf.IsNull()) {
            buildPlate.LoadInitSurface(surf);

            if (!points && !curves) {
                Standard_Real U1,U2,V1,V2;
                surf->Bounds(U1,U2,V1,V2);
                buildPlate.Add(new GeomPlate_PointConstraint(surf->Value(U1,V1),0));
                buildPlate.Add(new GeomPlate_PointConstraint(surf->Value(U1,V2),0));
                buildPlate.Add(new GeomPlate_PointConstraint(surf->Value(U2,V1),0));
                buildPlate.Add(new GeomPlate_PointConstraint(surf->Value(U2,V2),0));
            }
        }

        if (points) {
            Py::Sequence list(points);
            for (Py::Sequence::iterator it = list.begin(); it != list.end(); ++it) {
                Base::Vector3d vec = Py::Vector(*it).toVector();
                Handle(GeomPlate_PointConstraint) PCont = new GeomPlate_PointConstraint(gp_Pnt(vec.x,vec.y,vec.z),0);
                buildPlate.Add(PCont);
            }
        }

        if (curves) {
            Py::Sequence list(curves);
            for (Py::Sequence::iterator it = list.begin(); it != list.end(); ++it) {
                //TODO
            }
        }

        buildPlate.Perform();
        getGeomPlateSurfacePtr()->setHandle(buildPlate.Surface());
        return 0;
    }
    catch (Standard_Failure) {
        Handle_Standard_Failure e = Standard_Failure::Caught();
        PyErr_SetString(PartExceptionOCCError, e->GetMessageString());
        return -1;
    }
}