public void parseSvgFile(ref MultiShape @out, string fileName, string groupName, int segmentsNumber) { mNumSeg = (uint)segmentsNumber; //rapidxml::xml_document<> XMLDoc; // character type defaults to char XmlDocument XMLDoc = new XmlDocument(); // DataStreamPtr stream = ResourceGroupManager::getSingleton().openResource(fileName, groupName); //char* svg = strdup(stream->getAsString().c_str()); //XMLDoc.parse<0>(svg); //rapidxml::xml_node<>* pXmlRoot = XMLDoc.first_node("svg"); XmlNode pXmlRoot = XMLDoc.SelectSingleNode("svg"); //if (pXmlRoot == NULL) return; if (pXmlRoot == null) { return; } //rapidxml::xml_node<>* pXmlChildNode = pXmlRoot->first_node(); XmlNode pXmlChildNode = pXmlRoot.FirstChild; while (pXmlChildNode != null) { parseChildNode(ref @out, pXmlChildNode); //pXmlChildNode = pXmlChildNode->next_sibling(); pXmlChildNode = pXmlChildNode.NextSibling; } }
//----------------------------------------------------------------------- void parseRect(ref MultiShape @out, XmlNode pRectNode) { float width = getAttribReal(pRectNode, "width"); float height = getAttribReal(pRectNode, "height"); if (width <= 0.0f || height <= 0.0f) { return; } Shape s = new RectangleShape().setHeight(height).setWidth(width).realizeShape(); // if(pRectNode->first_attribute("id")) // ss.id = pRectNode->first_attribute("id")->value(); //Vector2 position; float position_x = getAttribReal(pRectNode, "x"); float position_y = getAttribReal(pRectNode, "y"); Vector2 position = new Vector2(position_x, position_y); // Our rectangle are centered, but svg rectangles are defined by their corners position += 0.5f * new Vector2(width, height); Vector2 trans = getAttribTranslate(pRectNode); position += trans; s.translate(position); @out.addShape(s); }
public Triangulator(Shape ss, MultiShape multis, Triangle2D t2d, bool removeOutSide, std_vector <Segment2D> listToTriangulate) { mShapeToTriangulate = ss; mMultiShapeToTriangulate = multis; mManualSuperTriangle = t2d; mRemoveOutside = removeOutSide; mSegmentListToTriangulate = listToTriangulate; }
/// Append every shape of an other multishape to the current multiShape public void addMultiShape(MultiShape other) { //for (List<Shape>.Enumerator it = STLAllocator<U, AllocPolicy>.mShapes.GetEnumerator(); it!=STLAllocator<U, AllocPolicy>.mShapes.end(); ++it) foreach (var it in other.mShapes) { mShapes.push_back(it); } }
/// Default ctor //Triangulator() : mShapeToTriangulate(0), mMultiShapeToTriangulate(0), mManualSuperTriangle(0), mRemoveOutside(true), mSegmentListToTriangulate(0) //{ //} public Triangulator() { mShapeToTriangulate = null; mMultiShapeToTriangulate = null; mManualSuperTriangle = null; mRemoveOutside = true; mSegmentListToTriangulate = null; }
// //ORIGINAL LINE: Lathe(Shape* shapeToExtrude = 0, uint numSeg = 16) : mShapeToExtrude(shapeToExtrude), mMultiShapeToExtrude(0), mNumSeg(numSeg), mAngleBegin(0), mAngleEnd((Ogre::Radian)Ogre::Math::TWO_PI), mClosed(true), mCapped(true) public Lathe(Shape shapeToExtrude, uint numSeg) { mShapeToExtrude = shapeToExtrude; mMultiShapeToExtrude = null; mNumSeg = numSeg; mAngleBegin = 0f; mAngleEnd = (Radian)Math.TWO_PI; mClosed = true; mCapped = true; }
//----------------------------------------------------------------------- void parsePath(ref MultiShape @out, XmlNode pPathNode) { //if (pPathNode->first_attribute("d")) if (pPathNode.Attributes["d"] != null) { string temp = xtrim(pPathNode.Attributes["d"].Value, " .-0123456789mMlLhHvVcCsSqQtTaAzZ"); std_vector <string> parts = split(temp, " "); for (int i = 0; i < parts.size(); i++) { if (parts[i].Length > 1 && !(parts[i][0] == '-' || ('0' <= parts[i][0] && parts[i][0] <= '9'))) { parts.insert(parts.begin() + i + 1, parts[i] + 1); //parts[i].erase(1, parts[i].size()); parts[i] = parts[i].Remove(1); } } SvgLoaderPath sp = new SvgLoaderPath(parts, mNumSeg); if (!sp.isValid()) { return; } Shape ss = sp.getSvgShape(); Vector2 line = ss.getPoint(1) - ss.getPoint(0); //Real deg = line.angleBetween(ss.getPoint(2) - ss.getPoint(0)).valueDegrees(); float deg = Utils.angleBetween(line, ss.getPoint(2) - ss.getPoint(0)).ValueDegrees; if ((0 <= deg && deg <= 180.0f) || (-180.0f <= deg && deg <= 0)) { ss.setOutSide(Side.SIDE_LEFT); } else { ss.setOutSide(Side.SIDE_RIGHT); } //if(pPathNode->first_attribute("id")) // ss.id = pPathNode->first_attribute("id")->value(); ss.translate(getAttribTranslate(pPathNode)); @out.addShape(ss); } }
//----------------------------------------------------------------------- void parseCircle(ref MultiShape @out, XmlNode pCircleNode) { float r = getAttribReal(pCircleNode, "r"); if (r <= 0.0f) { return; } Shape s = new CircleShape().setNumSeg(mNumSeg).setRadius(r).realizeShape(); // if(pCircleNode->first_attribute("id")) // ss.id = pCircleNode->first_attribute("id")->value(); float position_x = getAttribReal(pCircleNode, "cx"); float position_y = getAttribReal(pCircleNode, "cy"); Vector2 position = new Vector2(position_x, position_y); Vector2 trans = getAttribTranslate(pCircleNode); position += trans; s.translate(position); @out.addShape(s); }
//----------------------------------------------------------------------- void parseEllipse(ref MultiShape @out, XmlNode pEllipseNode) { float rx = getAttribReal(pEllipseNode, "rx"); float ry = getAttribReal(pEllipseNode, "ry"); if (rx <= 0.0f || ry <= 0.0f) { return; } Shape s = new EllipseShape().setNumSeg(mNumSeg).setRadiusX(rx).setRadiusY(ry).realizeShape(); // if(pEllipseNode->first_attribute("id")) // ss.id = pEllipseNode->first_attribute("id")->value(); float position_x = getAttribReal(pEllipseNode, "cx"); float position_y = getAttribReal(pEllipseNode, "cy"); Vector2 position = new Vector2(position_x, position_y); Vector2 trans = getAttribTranslate(pEllipseNode); position += trans; s.translate(position); @out.addShape(s); }
//----------------------------------------------------------------------- //private: void parseChildNode(ref MultiShape @out, XmlNode pChild) { string name = pChild.Name; if (name.Length > 3) { //if (stricmp(name.c_str(), "rect") == 0) if (stricmp(name, "rect") == 0) { parseRect(ref @out, pChild); } else if (stricmp(name, "circle") == 0) { parseCircle(ref @out, pChild); } else if (stricmp(name, "ellipse") == 0) { parseEllipse(ref @out, pChild); } else if (stricmp(name, "polygon") == 0 || stricmp(name, "polyline") == 0) { parsePolygon(ref @out, pChild); } else if (stricmp(name, "path") == 0) { parsePath(ref @out, pChild); // svg path is a shape } } //rapidxml::xml_node<>* pSubChildNode = pChild->first_node(); XmlNode pSubChildNode = pChild.FirstChild; while (pSubChildNode != null) { parseChildNode(ref @out, pSubChildNode); pSubChildNode = pSubChildNode.NextSibling; } }
//----------------------------------------------------------------------- void parsePolygon(ref MultiShape @out, XmlNode pPolygonNode) { //if (pPolygonNode->first_attribute("points")) if (pPolygonNode.Attributes["points"] != null) { //if (pPolygonNode->first_attribute("points")->value_size() < 3) return; if (string.IsNullOrEmpty(pPolygonNode.Attributes["points"].Value)) { return; } if (pPolygonNode.Attributes["points"].Value.Length < 3) { return; } string temp = xtrim(pPolygonNode.Attributes["points"].Value); std_vector <string> pts = split(temp, " "); if (pts.size() == 0) { return; } Shape s = new Shape(); for (int i = 0; i < pts.size() - 1; i += 2) { s.addPoint(parseReal(pts[i + 0]), parseReal(pts[i + 1])); } if (s.getPointsReference().size() == 0) { return; } s.close(); // if(pPolygonNode->first_attribute("id")) // ss.id = pPolygonNode->first_attribute("id")->value(); s.translate(getAttribTranslate(pPolygonNode)); @out.addShape(s); } }
//----------------------------------------------------------------------- // //ORIGINAL LINE: void _latheCapImpl(TriangleBuffer& buffer) const private void _latheCapImpl(ref TriangleBuffer buffer) { std_vector <int> indexBuffer = new std_vector <int>(); std_vector <Vector2> pointList = new std_vector <Vector2>(); buffer.rebaseOffset(); Triangulator t = new Triangulator(); Shape shapeCopy = new Shape(); MultiShape multishapeCopy = new MultiShape(); if (mShapeToExtrude != null) { // //ORIGINAL LINE: shapeCopy = *mShapeToExtrude; shapeCopy = (mShapeToExtrude); shapeCopy.close(); t.setShapeToTriangulate(shapeCopy); } else { // //ORIGINAL LINE: multishapeCopy = *mMultiShapeToExtrude; multishapeCopy = (mMultiShapeToExtrude); multishapeCopy.close(); t.setMultiShapeToTriangulate(mMultiShapeToExtrude); } t.triangulate(indexBuffer, pointList); buffer.estimateIndexCount(2 * (uint)indexBuffer.Count); buffer.estimateVertexCount(2 * (uint)pointList.Count); //begin cap buffer.rebaseOffset(); Quaternion q = new Quaternion(); q.FromAngleAxis(mAngleBegin, Vector3.UNIT_Y); for (int j = 0; j < pointList.size(); j++) { Vector2 vp2 = pointList[j]; Vector3 vp = new Vector3(vp2.x, vp2.y, 0); //C++ TO C# CONVERTER WARNING: The following line was determined to be a copy constructor call - this should be verified and a copy constructor should be created if it does not yet exist: //ORIGINAL LINE: Vector3 normal = Vector3::UNIT_Z; Vector3 normal = (Vector3.UNIT_Z); addPoint(ref buffer, q * vp, q * normal, vp2); } for (int i = 0; i < indexBuffer.size() / 3; i++) { buffer.index(indexBuffer[i * 3]); buffer.index(indexBuffer[i * 3 + 1]); buffer.index(indexBuffer[i * 3 + 2]); } //end cap buffer.rebaseOffset(); q.FromAngleAxis(mAngleEnd, Vector3.UNIT_Y); for (int j = 0; j < pointList.size(); j++) { Vector2 vp2 = pointList[j]; Vector3 vp = new Vector3(vp2.x, vp2.y, 0); Vector3 normal = -Vector3.UNIT_Z; addPoint(ref buffer, q * vp, q * normal, vp2); } for (int i = 0; i < indexBuffer.size() / 3; i++) { buffer.index(indexBuffer[i * 3]); buffer.index(indexBuffer[i * 3 + 2]); buffer.index(indexBuffer[i * 3 + 1]); } }
// * Sets the multiShape to extrude // * If a shape is already defined, auto-disables it // * The shapes in this multi-shape are assumed to be defined in the X>=0 half-plane // public Lathe setMultiShapeToExtrude(MultiShape multiShapeToExtrude) { mMultiShapeToExtrude = multiShapeToExtrude; mShapeToExtrude = null; return(this); }
// * Sets the shape to extrude // * If a multishape is already defined, auto-disables it // * The shape is assumed to be defined in the X>=0 half-plane // public Lathe setShapeToExtrude(Shape shapeToExtrude) { mShapeToExtrude = shapeToExtrude; mMultiShapeToExtrude = null; return(this); }
// * // * Build a MultiShape from chars (one Shape per character) // * \exception Ogre::InternalErrorException Freetype error // * \todo Need to split shapes of multi region chars. For example the letter \c O // * has two shapes, but they are connected to one shape. // public MultiShape realizeShapes() { MultiShape retVal = new MultiShape(); FT_Library ftlib = new FT_Library(); FT_Face face = new FT_Face(); FT_GlyphSlot slot = new FT_GlyphSlot(); FT_Error error = FT_Init_FreeType(ftlib); if (error == 0) { error = FT_New_Face(ftlib, getFontFileByName().c_str(), 0, face); if (error == FT_Err_Unknown_File_Format) { //C++ TO C# CONVERTER TODO TASK: There is no direct equivalent in C# to the C++ __LINE__ macro: //C++ TO C# CONVERTER TODO TASK: There is no direct equivalent in C# to the C++ __FILE__ macro: throw ExceptionFactory.create(Mogre.ExceptionCodeType <Mogre.Exception.ExceptionCodes.ERR_INTERNAL_ERROR>(), "FreeType ERROR: FT_Err_Unknown_File_Format", "Procedural::TextShape::realizeShapes()", __FILE__, __LINE__); ; } else if (error != null) { //C++ TO C# CONVERTER TODO TASK: There is no direct equivalent in C# to the C++ __LINE__ macro: //C++ TO C# CONVERTER TODO TASK: There is no direct equivalent in C# to the C++ __FILE__ macro: throw ExceptionFactory.create(Mogre.ExceptionCodeType <Mogre.Exception.ExceptionCodes.ERR_INTERNAL_ERROR>(), "FreeType ERROR: FT_New_Face - " + StringConverter.toString(error), "Procedural::TextShape::realizeShapes()", __FILE__, __LINE__); ; } else { FT_Set_Pixel_Sizes(face, 0, mFontSize); int px = 0; int py = 0; slot = face.glyph; for (int n = 0; n < mText.length(); n++) { error = FT_Load_Char(face, mText[n], FT_LOAD_NO_BITMAP); if (error != null) { continue; } Shape s = new Shape(); int nContours = face.glyph.outline.n_contours; int startPos = 0; string tags = face.glyph.outline.tags; FT_Vector[] vec = face.glyph.outline.points; for (int k = 0; k < nContours; k++) { if (k > 0) { startPos = face.glyph.outline.contours[k - 1] + 1; } int endPos = face.glyph.outline.contours[k] + 1; Vector2 lastPoint = Vector2.ZERO; for (int j = startPos; j < endPos; j++) { if (FT_CURVE_TAG(tags[j]) == FT_CURVE_TAG_ON) { lastPoint = Vector2((float)vec[j].x, (float)vec[j].y); s.addPoint(lastPoint / 64.0f); } else { if (FT_CURVE_TAG(tags[j]) == FT_CURVE_TAG_CUBIC) { int prevPoint = j - 1; if (j == 0) { prevPoint = endPos - 1; } int nextIndex = j + 1; if (nextIndex >= endPos) { nextIndex = startPos; } Vector2[] nextPoint = new Vector2[nextIndex]((float)vec.x, (float)vec[nextIndex].y); if ((FT_CURVE_TAG(tags[prevPoint]) != FT_CURVE_TAG_ON) && (FT_CURVE_TAG(tags[prevPoint]) == FT_CURVE_TAG_CUBIC)) { BezierCurve2 bc = new BezierCurve2(); bc.addPoint(Vector2((float)vec[prevPoint].x, (float)vec[prevPoint].y) / 64.0f); bc.addPoint(Vector2((float)vec[j].x, (float)vec[j].y) / 64.0f); bc.addPoint(Vector2((float)vec[nextIndex].x, (float)vec[nextIndex].y) / 64.0f); s.appendShape(bc.realizeShape()); } } else { Vector2[] conicPoint = new Vector2[j]((float)vec.x, (float)vec[j].y); if (j == startPos) { if ((FT_CURVE_TAG(tags[endPos - 1]) != FT_CURVE_TAG_ON) && (FT_CURVE_TAG(tags[endPos - 1]) != FT_CURVE_TAG_CUBIC)) { Vector2[] lastConnic = new Vector2[endPos - 1]((float)vec.x, (float)vec[endPos - 1].y); lastPoint = (conicPoint + lastConnic) / 2; } } int nextIndex = j + 1; if (nextIndex >= endPos) { nextIndex = startPos; } Vector2[] nextPoint = new Vector2[nextIndex]((float)vec.x, (float)vec[nextIndex].y); bool nextIsConnic = (FT_CURVE_TAG(tags[nextIndex]) != FT_CURVE_TAG_ON) && (FT_CURVE_TAG(tags[nextIndex]) != FT_CURVE_TAG_CUBIC); if (nextIsConnic) { nextPoint = (conicPoint + nextPoint) / 2; } int pc = s.getPointCount(); BezierCurve2 bc = new BezierCurve2(); if (pc == 0) { bc.addPoint(Vector2.ZERO); } else { bc.addPoint(s.getPoint(pc - 1)); } bc.addPoint(lastPoint / 64.0f); bc.addPoint(conicPoint / 64.0f); bc.addPoint(nextPoint / 64.0f); if (pc == 0) { s.appendShape(bc.realizeShape()); } else { List <Vector2> subShape = bc.realizeShape().getPoints(); for (List <Vector2> .Enumerator iter = subShape.GetEnumerator(); iter.MoveNext(); iter++) { if (iter != subShape.GetEnumerator()) { s.addPoint(iter.Current); } } } if (nextIsConnic) { // //ORIGINAL LINE: lastPoint = nextPoint; lastPoint = (nextPoint); } } } } } s.close(); s.translate((float)px, (float)py); retVal.addShape(s); px += slot.advance.x >> 6; py += slot.advance.y >> 6; } FT_Done_Face(face); } FT_Done_FreeType(ftlib); } else { //C++ TO C# CONVERTER TODO TASK: There is no direct equivalent in C# to the C++ __LINE__ macro: //C++ TO C# CONVERTER TODO TASK: There is no direct equivalent in C# to the C++ __FILE__ macro: throw ExceptionFactory.create(Mogre.ExceptionCodeType <Mogre.Exception.ExceptionCodes.ERR_INTERNAL_ERROR>(), "FreeType ERROR: FT_Init_FreeTyp", "Procedural::TextShape::realizeShapes()", __FILE__, __LINE__); ; } return(retVal); }
//----------------------------------------------------------------------- public static void _extrudeCapImpl(ref TriangleBuffer buffer, MultiShape multiShapeToExtrude, MultiPath extrusionMultiPath, TrackMap scaleTracks, TrackMap rotationTracks) { std_vector <int> indexBuffer = new std_vector <int>(); // PointList pointList; std_vector <Vector2> pointList = new std_vector <Vector2>(); Triangulator t = new Triangulator(); t.setMultiShapeToTriangulate(multiShapeToExtrude); t.triangulate(indexBuffer, pointList); for (uint i = 0; i < extrusionMultiPath.getPathCount(); ++i) { Path extrusionPath = extrusionMultiPath.getPath((int)i); Track scaleTrack = null; Track rotationTrack = null; if (scaleTracks.find(i) != -1) // scaleTracks.end()) { scaleTrack = scaleTracks[i]; //.find(i).second; } if (rotationTracks.find(i) != -1) // rotationTracks.end()) { rotationTrack = rotationTracks[i]; //.find(i).second; } //begin cap //if (extrusionMultiPath.getIntersectionsMap().find(MultiPath.PathCoordinate(i, 0)) == extrusionMultiPath.getIntersectionsMap().end()) if (extrusionMultiPath.getIntersectionsMap().find(new MultiPath.PathCoordinate(i, 0)) == -1) { buffer.rebaseOffset(); buffer.estimateIndexCount((uint)indexBuffer.Count); buffer.estimateVertexCount((uint)pointList.Count); Quaternion qBegin = Utils._computeQuaternion(extrusionPath.getDirectionAfter(0)); if (rotationTrack != null) { float angle = rotationTrack.getFirstValue(); qBegin = qBegin * new Quaternion((Radian)angle, Vector3.UNIT_Z); } float scaleBegin = 1.0f; if (scaleTrack != null) { scaleBegin = scaleTrack.getFirstValue(); } for (int j = 0; j < pointList.size(); j++) { Vector2 vp2 = pointList[j]; Vector3 vp = new Vector3(vp2.x, vp2.y, 0); Vector3 normal = -Vector3.UNIT_Z; Vector3 newPoint = extrusionPath.getPoint(0) + qBegin * (scaleBegin * vp); buffer.vertex(newPoint, qBegin * normal, vp2); } for (int i2 = 0; i2 < indexBuffer.Count / 3; i2++) { buffer.index(indexBuffer[i2 * 3]); buffer.index(indexBuffer[i2 * 3 + 2]); buffer.index(indexBuffer[i2 * 3 + 1]); } } //end cap //if (extrusionMultiPath.getIntersectionsMap().find(MultiPath.PathCoordinate(i, extrusionPath.getSegCount())) == extrusionMultiPath.getIntersectionsMap().end()) if (extrusionMultiPath.getIntersectionsMap().find(new MultiPath.PathCoordinate(i, (uint)extrusionPath.getSegCount())) == -1) { buffer.rebaseOffset(); buffer.estimateIndexCount((uint)indexBuffer.Count); buffer.estimateVertexCount((uint)pointList.Count); Quaternion qEnd = Utils._computeQuaternion(extrusionPath.getDirectionBefore(extrusionPath.getSegCount())); if (rotationTrack != null) { float angle = rotationTrack.getLastValue(); qEnd = qEnd * new Quaternion((Radian)angle, Vector3.UNIT_Z); } float scaleEnd = 1.0f; if (scaleTrack != null) { scaleEnd = scaleTrack.getLastValue(); } for (int j = 0; j < pointList.Count; j++) { Vector2 vp2 = pointList[j]; Vector3 vp = new Vector3(vp2.x, vp2.y, 0f); //C++ TO C# CONVERTER WARNING: The following line was determined to be a copy constructor call - this should be verified and a copy constructor should be created if it does not yet exist: //ORIGINAL LINE: Vector3 normal = Vector3::UNIT_Z; Vector3 normal = (Vector3.UNIT_Z); Vector3 newPoint = extrusionPath.getPoint(extrusionPath.getSegCount()) + qEnd * (scaleEnd * vp); buffer.vertex(newPoint, qEnd * normal, vp2); } for (int ii = 0; ii < indexBuffer.Count / 3; ii++) { buffer.index(indexBuffer[ii * 3]); buffer.index(indexBuffer[ii * 3 + 1]); buffer.index(indexBuffer[ii * 3 + 2]); } } } }
//* Sets the multishape to extrude. Mutually exclusive with setShapeToExtrude. public Extruder setMultiShapeToExtrude(MultiShape multiShapeToExtrude) { mMultiShapeToExtrude.clear(); mMultiShapeToExtrude.addMultiShape(multiShapeToExtrude); return(this); }
/// Sets multi shape to triangulate public Triangulator setMultiShapeToTriangulate(MultiShape multiShape) { mMultiShapeToTriangulate = multiShape; return(this); }
/// Sets shape to triangulate public Triangulator setShapeToTriangulate(Shape shape) { mShapeToTriangulate = shape; mMultiShapeToTriangulate = null; return(this); }
//public: /** * Parses a SVG file * @param out MultiShape object where to store shapes from svg file * @param fileName Filename of svg file * @param groupName Resource group where svg file is listed * @param segmentsNumber Number of segments for curves */ //void parseSvgFile(MultiShape& out, const Ogre::String& fileName, const Ogre::String& groupName = Ogre::ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME, int segmentsNumber = 8); public void parseSvgFile(ref MultiShape ms, string fileName) { parseSvgFile(ref ms, fileName, Mogre.ResourceGroupManager.DEFAULT_RESOURCE_GROUP_NAME, 8); }