private static IfcShellBasedSurfaceModel createShellBasedSurfaceModel(IfcStore model, Vector3 origin, Mesh mesh, out RepresentationType representationType, out RepresentationIdentifier representationIdentifier) { //Serilog.Log.Logger = new LoggerConfiguration() // .MinimumLevel.Debug() // .WriteTo.File(System.Configuration.ConfigurationManager.AppSettings["LogFilePath"]) // .CreateLogger(); if (mesh.MaxFaceCorners < 3) { //Log.Error("Creation of IfcShellBasedSurfaceModel unsuccessful. Mesh has no Faces"); throw new Exception("Mesh has no Faces"); } using (var txn = model.BeginTransaction("Create Mesh")) { var vmap = new Dictionary <int, int>(); var cpl = new List <IfcCartesianPoint>(); for (int i = 0, j = 0; i < mesh.Points.Count; i++) { if (mesh.VertexEdges[i] < 0) { continue; } vmap.Add(i, j); var pt = mesh.Points[i]; cpl.Add(model.Instances.New <IfcCartesianPoint>(c => c.SetXYZ(pt.X - origin.X, pt.Y - origin.Y, pt.Z - origin.Z))); j++; } var sbsm = model.Instances.New <IfcShellBasedSurfaceModel>(s => s.SbsmBoundary.Add(model.Instances.New <IfcOpenShell>(o => o.CfsFaces .AddRange(mesh.FaceEdges.Select(fe => model.Instances.New <IfcFace>(x => x.Bounds .Add(model.Instances.New <IfcFaceOuterBound>(b => { b.Bound = model.Instances.New <IfcPolyLoop>(p => { int curr = fe; do { p.Polygon.Add(cpl[vmap[mesh.EdgeVertices[curr]]]); curr = mesh.EdgeNexts[curr]; } while(curr != fe && p.Polygon.Count < mesh.MaxFaceCorners); }); b.Orientation = true; })))))))); txn.Commit(); representationIdentifier = RepresentationIdentifier.Body; representationType = RepresentationType.SurfaceModel; //Log.Information("IfcShellBasedSurfaceModel created"); return(sbsm); } }
public override string GetStepParameters() { var parameters = new List <string>(); parameters.Add(ContextOfItems != null ? ContextOfItems.ToStepValue() : "$"); parameters.Add(RepresentationIdentifier != null ? RepresentationIdentifier.ToStepValue() : "$"); parameters.Add(RepresentationType != null ? RepresentationType.ToStepValue() : "$"); parameters.Add(Items != null ? Items.ToStepValue() : "$"); return(string.Join(", ", parameters.ToArray())); }
/// Achtung mesh muss zwingend aus Dreiecken Bestehen private static IfcTriangulatedFaceSet createTriangulatedFaceSet(IfcStore model, Vector3 origin, Mesh mesh, out RepresentationType representationType, out RepresentationIdentifier representationIdentifier) { if (mesh.MaxFaceCorners != 3 || mesh.MinFaceCorners != 3) { throw new Exception("Mesh is not Triangular"); } using (var txn = model.BeginTransaction("Create TIN")) { var vmap = new Dictionary <int, int>(); var cpl = model.Instances.New <IfcCartesianPointList3D>(c => { for (int i = 0, j = 0; i < mesh.Points.Count; i++) { if (mesh.VertexEdges[i] < 0) { continue; } vmap.Add(i, j + 1); var pt = mesh.Points[i]; var coo = c.CoordList.GetAt(j++); coo.Add(pt.X - origin.X); coo.Add(pt.Y - origin.Y); coo.Add(pt.Z - origin.Z); } }); var tfs = model.Instances.New <IfcTriangulatedFaceSet>(t => { t.Closed = false; // nur bei Volumenkörpern t.Coordinates = cpl; int cnt = 0; foreach (int fe in mesh.FaceEdges) { var fi = t.CoordIndex.GetAt(cnt++); fi.Add(vmap[mesh.EdgeVertices[fe]]); fi.Add(vmap[mesh.EdgeVertices[mesh.EdgeNexts[fe]]]); fi.Add(vmap[mesh.EdgeVertices[mesh.EdgeNexts[mesh.EdgeNexts[fe]]]]); } }); txn.Commit(); representationIdentifier = RepresentationIdentifier.Body; representationType = RepresentationType.Tessellation; return(tfs); } }
private static IfcShellBasedSurfaceModel createShellBasedSurfaceModelViaTin(IfcStore model, Vector3 origin, Tin tin, out RepresentationType representationType, out RepresentationIdentifier representationIdentifier) { /* Validierung -> bereits bei Reader implementieren? * if (mesh.MaxFaceCorners < 3) * { throw new Exception("Mesh has no Faces"); } */ //init Logger Logger logger = LogManager.GetCurrentClassLogger(); using (var txn = model.BeginTransaction("Create Tin")) { var vmap = new Dictionary <int, int>(); var cpl = new List <IfcCartesianPoint>(); for (int i = 0, j = 0; i < tin.Points.Count; i++) { vmap.Add(i, j); var pt = tin.Points[i]; cpl.Add(model.Instances.New <IfcCartesianPoint>(c => c.SetXYZ(pt.X - origin.X, pt.Y - origin.Y, pt.Z - origin.Z))); j++; } var sbsm = model.Instances.New <IfcShellBasedSurfaceModel>(s => s.SbsmBoundary.Add(model.Instances.New <IfcOpenShell>(o => o.CfsFaces .AddRange(tin.TriangleVertexPointIndizes().Select(tri => model.Instances.New <IfcFace>(x => x.Bounds .Add(model.Instances.New <IfcFaceOuterBound>(b => { b.Bound = model.Instances.New <IfcPolyLoop>(p => { p.Polygon.Add(cpl[vmap[tri[0]]]); p.Polygon.Add(cpl[vmap[tri[1]]]); p.Polygon.Add(cpl[vmap[tri[2]]]); }); b.Orientation = true; })))))))); //logger.Debug("Processed: " + ); txn.Commit(); representationIdentifier = RepresentationIdentifier.Body; representationType = RepresentationType.SurfaceModel; //TRASHLÖSUNG below: long numTri = ((sbsm.Model.Instances.Count - vmap.Count) / 3) - 10; logger.Debug("Processed: " + vmap.Count + " points; " + numTri + " triangels)"); return(sbsm); } }
private static IfcShapeRepresentation createShapeRepresentation(IfcStore model, IfcGeometricRepresentationItem item, RepresentationIdentifier identifier, RepresentationType type) { // //begin a transaction using (var txn = model.BeginTransaction("Create Shaperepresentation")) { //Create a Definition shape to hold the geometry var shape = model.Instances.New <IfcShapeRepresentation>(s => { s.ContextOfItems = model.Instances.OfType <IfcGeometricRepresentationContext>().FirstOrDefault(); s.RepresentationType = type.ToString(); s.RepresentationIdentifier = identifier.ToString(); s.Items.Add(item); }); txn.Commit(); return(shape); } }
/// <summary> /// Geländemodell aus Punkten und Bruchlinien /// </summary> /// <param name="model"> </param> /// <param name="points"> Geländepunkte </param> /// <param name="breaklines"> Bruchlinien mit indizes der Punkte </param> /// <returns> </returns> private static IfcGeometricCurveSet createGeometricCurveSetViaTin(IfcStore model, Vector3 origin, Tin tin, double?breakDist, out RepresentationType representationType, out RepresentationIdentifier representationIdentifier) { //init Logger Logger logger = LogManager.GetCurrentClassLogger(); //begin a transaction using (var txn = model.BeginTransaction("Create DTM")) { // CartesianPoints erzeugen //TODO: Punkte filtern, die nicht im DGM enthalten sind var cps = tin.Points.Select(p => model.Instances.New <IfcCartesianPoint>(c => c.SetXYZ(p.X - origin.X, p.Y - origin.Y, p.Z - origin.Z))).ToList(); // DTM var dtm = model.Instances.New <IfcGeometricCurveSet>(g => { var edges = new HashSet <TupleIdx>(); g.Elements.AddRange(cps); if (breakDist is double dist) { /* ÜBERARBEITEN - ist noch die Funktionalität aus MESH * // Hilfsfunktion zum Punkte auf Kante erzeugen * void addEdgePoints(Point3 start, Point3 dest) * { * var dir = dest - start; * double len = Vector3.Norm(dir); * double fac = len / dist; * if (fac > 1.0) * { * start -= origin; * dir /= len; * double currLen = dist; * while (currLen < len) * { * var p = start + (dir * currLen); * g.Elements.Add(model.Instances.New<IfcCartesianPoint>(c => c.SetXYZ(p.X, p.Y, p.Z))); * currLen += dist; * } * } * } * /* * // evtl. Bruchlinien erzeugen * foreach (var edge in mesh.FixedEdges) * { * addEdgePoints(mesh.Points[edge.Idx1], mesh.Points[edge.Idx2]); * edges.Add(edge); * } * * // Kanten der Faces (falls vorhanden und ohne Doppelung) * foreach (var edge in mesh.EdgeIndices.Keys) * { * if (!edges.Contains(TupleIdx.Flipped(edge)) && edges.Add(edge)) * { addEdgePoints(mesh.Points[edge.Idx1], mesh.Points[edge.Idx2]); } * } */ } else { //Read out each triangle foreach (var tri in tin.TriangleVertexPointIndizes()) { //first edge g.Elements.Add(model.Instances.New <IfcPolyline>(p => p.Points.AddRange(new[] { cps[tri[0]], cps[tri[1]] }))); //next edge g.Elements.Add(model.Instances.New <IfcPolyline>(p => p.Points.AddRange(new[] { cps[tri[1]], cps[tri[2]] }))); //last edge g.Elements.Add(model.Instances.New <IfcPolyline>(p => p.Points.AddRange(new[] { cps[tri[2]], cps[tri[0]] }))); } } }); int numEdges = dtm.Elements.Count - cps.Count; logger.Debug("Processed: " + cps.Count + " points; " + numEdges + " edges (of " + numEdges / 3 + " triangels)"); //nach dem commit von txn loggen .. nur für Debugging hier stehen lassen txn.Commit(); representationIdentifier = RepresentationIdentifier.SurveyPoints; representationType = RepresentationType.GeometricCurveSet; return(dtm); } }
/// <summary> /// Geländemodell aus Punkten und Bruchlinien /// </summary> /// <param name="model"> </param> /// <param name="points"> Geländepunkte </param> /// <param name="breaklines"> Bruchlinien mit indizes der Punkte </param> /// <returns> </returns> private static IfcGeometricCurveSet createGeometricCurveSet(IfcStore model, Vector3 origin, Mesh mesh, double?breakDist, out RepresentationType representationType, out RepresentationIdentifier representationIdentifier) { //Serilog.Log.Logger = new LoggerConfiguration() // .MinimumLevel.Debug() // .WriteTo.File(System.Configuration.ConfigurationManager.AppSettings["LogFilePath"]) // .CreateLogger(); //begin a transaction using (var txn = model.BeginTransaction("Create DTM")) { // CartesianPoints erzeugen var cps = mesh.Points.Select(p => model.Instances.New <IfcCartesianPoint>(c => c.SetXYZ(p.X - origin.X, p.Y - origin.Y, p.Z - origin.Z))).ToList(); // DTM var dtm = model.Instances.New <IfcGeometricCurveSet>(g => { var edges = new HashSet <TupleIdx>(); g.Elements.AddRange(cps); if (breakDist is double dist) { // Hilfsfunktion zum Punkte auf Kante erzeugen void addEdgePoints(Point3 start, Point3 dest) { var dir = dest - start; double len = Vector3.Norm(dir); double fac = len / dist; if (fac > 1.0) { start -= origin; dir /= len; double currLen = dist; while (currLen < len) { var p = start + (dir * currLen); g.Elements.Add(model.Instances.New <IfcCartesianPoint>(c => c.SetXYZ(p.X, p.Y, p.Z))); currLen += dist; } } } // evtl. Bruchlinien erzeugen foreach (var edge in mesh.FixedEdges) { addEdgePoints(mesh.Points[edge.Idx1], mesh.Points[edge.Idx2]); edges.Add(edge); } // Kanten der Faces (falls vorhanden und ohne Doppelung) foreach (var edge in mesh.EdgeIndices.Keys) { if (!edges.Contains(TupleIdx.Flipped(edge)) && edges.Add(edge)) { addEdgePoints(mesh.Points[edge.Idx1], mesh.Points[edge.Idx2]); } } } else { // evtl. Bruchlinien erzeugen foreach (var edge in mesh.FixedEdges) { g.Elements.Add(model.Instances.New <IfcPolyline>(p => p.Points.AddRange(new[] { cps[edge.Idx1], cps[edge.Idx2] }))); edges.Add(edge); } // Kanten der Faces (falls vorhanden und ohne Doppelung) foreach (var edge in mesh.EdgeIndices.Keys) { if (!edges.Contains(TupleIdx.Flipped(edge)) && edges.Add(edge)) { g.Elements.Add(model.Instances.New <IfcPolyline>(p => p.Points.AddRange(new[] { cps[edge.Idx1], cps[edge.Idx2] }))); } } } }); txn.Commit(); representationIdentifier = RepresentationIdentifier.SurveyPoints; representationType = RepresentationType.GeometricCurveSet; //Log.Information("IfcGeometricCurveSet created"); return(dtm); } }