Xbim Geometry error - c#

I am using the following C# code to access geometry data from an ifc4 file. The file contains only a wall created using Revit 2016. I am using Xbim library. This is my code:
class Program
{
private static readonly ILog logger =
LogManager.GetLogger(typeof(Program));
static string _ifcFile = #"C:\Examples\OneWall.ifc";
static void Main(string[] args)
{
BasicConfigurator.Configure();
IfcStore model = IfcStore.Open(_ifcFile);
Xbim3DModelContext context = new Xbim3DModelContext(model);
context.CreateContext();
XbimMeshGeometry3D mesh = mesh = (XbimMeshGeometry3D)context.ShapeGeometryMeshOf(context.ShapeInstances().FirstOrDefault());
//The rest of my code
}
}
I get the following error. I am using visual studio 2015.
1226 [1] DEBUG Xbim.Geometry.Engine.Interop.XbimCustomAssemblyResolver (null) - Loading assembly from: C:\Examples\ifcWall\ifcWall\bin\Debug\x86\Xbim.Geometry.Engine32.dll
1404 [1] DEBUG Xbim.Geometry.Engine.Interop.XbimCustomAssemblyResolver (null) - Loading assembly from: C:\Examples\ifcWall\ifcWall\bin\Debug\x86\Xbim.Geometry.Engine32.dll
Unhandled Exception: System.Exception: Invalid Geometry Command
at Xbim.ModelGeometry.Scene.XbimMeshGeometry3D.Read(String data, Nullable1 trans) in c:\BuildAgent\work\860c3b913b6c647f\Xbim.ModelGeometry.Scene\XbimMeshGeometry3D.cs:line 219
at Xbim.ModelGeometry.Scene.XbimMeshGeometry3D.Add(String mesh, Int16 productTypeId, Int32 productLabel, Int32 geometryLabel, Nullable1 transform, Int16 modelId) in c:\BuildAgent\work\860c3b913b6c647f\Xbim.ModelGeometry.Scene\XbimMeshGeometry3D.cs:line 669
at Xbim.ModelGeometry.Scene.Xbim3DModelContext.ShapeGeometryMeshOf(XbimShapeInstance shapeInstance) in c:\BuildAgent\work\860c3b913b6c647f\Xbim.ModelGeometry.Scene\Xbim3DModelContext.cs:line 1525
at ifcWall.Program.Main(String[] args) in C:\Users\karshenas\Documents\Courses\CEEN6840\VS_Projects\ifcWall\ifcWall\Program.cs:line 26
Any help to fix the error is appreciated.

You run into an area where API has changed and this particular functions expects data in a different format. If what you need is a triangulation of the shape this code should work for you:
using System.IO;
using Xbim.Common.Geometry;
using Xbim.Ifc;
using Xbim.ModelGeometry.Scene;
using Xbim.Common.XbimExtensions;
namespace CreateWexBIM
{
class Program
{
static void Main(string[] args)
{
const string file = #"4walls1floorSite.ifc";
var model = IfcStore.Open(file);
var context = new Xbim3DModelContext(model);
context.CreateContext();
var instances = context.ShapeInstances();
foreach (var instance in instances)
{
var geometry = context.ShapeGeometry(instance);
var data = ((IXbimShapeGeometryData)geometry).ShapeData;
using (var stream = new MemoryStream(data))
{
using (var reader = new BinaryReader(stream))
{
var mesh = reader.ReadShapeTriangulation();
}
}
}
}
}
}
The best is to ask in xBIM GitHub Issues and to share the file. IFC geometry can get very complex so it is not possible to really answer your question just based on the exception.

Related

ml.net sentiment analysis warning about format errors & bad values

I've been having a problem with my ml.net console app. This is my first time using ml.net in Visual Studio so I was following this tutorial from microsoft.com, which is a sentiment analysis using binary classification.
I'm trying to process some test data in the form of tsv files to get a positive or negative sentiment analysis, but in debugging I'm receiving warnings there being 1 format error and 2 bad values.
I decided to ask all you great devs here on Stack to see if anyone can help me find a solution.
Here's an image of the debugging below:
Here's the link to my test data:
wiki-data
wiki-test-data
Finally, here's my code for those who what to reproduce the problem:
There's 2 c# files: SentimentData.cs & Program.cs.
1 - SentimentData.cs:
using System;
using System.Collections.Generic;
using System.Text;
using Microsoft.ML.Runtime.Api;
namespace MachineLearningTut
{
public class SentimentData
{
[Column(ordinal: "0")]
public string SentimentText;
[Column(ordinal: "1", name: "Label")]
public float Sentiment;
}
public class SentimentPrediction
{
[ColumnName("PredictedLabel")]
public bool Sentiment;
}
}
2 - Program.cs:
using System;
using Microsoft.ML.Models;
using Microsoft.ML.Runtime;
using Microsoft.ML.Runtime.Api;
using Microsoft.ML.Trainers;
using Microsoft.ML.Transforms;
using System.Collections.Generic;
using System.Linq;
using Microsoft.ML;
using Microsoft.ML.Data;
using System.Threading.Tasks;
namespace MachineLearningTut
{
class Program
{
const string _dataPath = #".\Data\wikipedia-detox-250-line-data.tsv";
const string _testDataPath = #".\Data\wikipedia-detox-250-line-test.tsv";
const string _modelpath = #".\Data\Model.zip";
static async Task Main(string[] args)
{
var model = await TrainAsync();
Evaluate(model);
Predict(model);
}
public static async Task<PredictionModel<SentimentData, SentimentPrediction>> TrainAsync()
{
var pipeline = new LearningPipeline();
pipeline.Add(new TextLoader (_dataPath).CreateFrom<SentimentData>());
pipeline.Add(new TextFeaturizer("Features", "SentimentText"));
pipeline.Add(new FastForestBinaryClassifier() { NumLeaves = 5, NumTrees = 5, MinDocumentsInLeafs = 2 });
PredictionModel<SentimentData, SentimentPrediction> model = pipeline.Train<SentimentData, SentimentPrediction>();
await model.WriteAsync(path: _modelpath);
return model;
}
public static void Evaluate(PredictionModel<SentimentData, SentimentPrediction> model)
{
var testData = new TextLoader(_testDataPath).CreateFrom<SentimentData>();
var evaluator = new BinaryClassificationEvaluator();
BinaryClassificationMetrics metrics = evaluator.Evaluate(model, testData);
Console.WriteLine();
Console.WriteLine("PredictionModel quality metrics evaluation");
Console.WriteLine("-------------------------------------");
Console.WriteLine($"Accuracy: {metrics.Accuracy:P2}");
Console.WriteLine($"Auc: {metrics.Auc:P2}");
Console.WriteLine($"F1Score: {metrics.F1Score:P2}");
}
public static void Predict(PredictionModel<SentimentData, SentimentPrediction> model)
{
IEnumerable<SentimentData> sentiments = new[]
{
new SentimentData
{
SentimentText = "Please refrain from adding nonsense to Wikipedia."
},
new SentimentData
{
SentimentText = "He is the best, and the article should say that."
}
};
IEnumerable<SentimentPrediction> predictions = model.Predict(sentiments);
Console.WriteLine();
Console.WriteLine("Sentiment Predictions");
Console.WriteLine("---------------------");
var sentimentsAndPredictions = sentiments.Zip(predictions, (sentiment, prediction) => (sentiment, prediction));
foreach (var item in sentimentsAndPredictions)
{
Console.WriteLine($"Sentiment: {item.sentiment.SentimentText} | Prediction: {(item.prediction.Sentiment ? "Positive" : "Negative")}");
}
Console.WriteLine();
}
}
}
If anyone would like to see the code or more details on the solution, ask me on the chat and I'll send it. Thanks in advance!!! [Throws a Thumbs Up]
I think I got a fix for you. A couple of things to update:
First, I think you got your SentimentData properties switched to what the data has. Try changing it to
[Column(ordinal: "0", name: "Label")]
public float Sentiment;
[Column(ordinal: "1")]
public string SentimentText;
Second, use the useHeader parameter in the TextLoader.CreateFrom method. Don't forget to add that to the other one for the validation data, as well.
pipeline.Add(new TextLoader(_dataPath).CreateFrom<SentimentData>(useHeader: true));
With those two updates, I got the below output. Looks like a nice model with an AUC of 85%!
Another thing that helps with text type datasets is indicating that the text has quotes:
TextLoader("someFile.txt").CreateFrom<Input>(useHeader: true, allowQuotedStrings: true)
There is bad formated value on 252 and 253 rows. May me there fields wich contains the delimiter charachter.
If you post code or sample data we can be more precise.

Routing JSON data to Event Hubs in Azure

I have a situation where I need to send JSON data (a JSON file, not convert to JSON) to Time Series Insights via Event Hubs. But I am not able to send the data due to my lack of experience in C#.
I am able to send other sample messages but not JSON. How can I do that?
Any help or insight would be appreciated.
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Globalization;
using System.IO;
using Microsoft.ServiceBus.Messaging;
namespace ConsoleApp5
{
class Program
{
static string _connectionString = "Endpoint..;
static async Task MainAsync(string[] args)
{
var client = EventHubClient.CreateFromConnectionString(_connectionString, "eventhub");
var json = File.ReadAllText(#"C:\Users\Shyam\Downloads\personal.json");
var eventData = new EventData(Encoding.UTF8.GetBytes(json));
await EventHubClient.SendAsync(eventData);
}
}
}
It throws an error in the async method though.
Severity Code Description Project File Line Suppression State
Error CS0120 An object reference is required for the non-static field, method, or property 'EventHubClient.SendAsync(EventData)' ConsoleApp5 C:\Users\Shyam\source\repos\ConsoleApp5\ConsoleApp5\Program.cs 21 Active
UPDATE:
namespace jsonData
{
using System;
using System.Text;
using System.IO;
using System.Threading.Tasks;
using Microsoft.Azure.EventHubs;
public class Program
{
private static EventHubClient eventHubClient;
private const string EhConnectionString = "Endpoint=sb://";
private const string EhEntityPath = "hub";
public static void Main(string[] args)
{
MainAsync(args).GetAwaiter().GetResult();
}
private static async Task MainAsync(string[] args)
{
// Creates an EventHubsConnectionStringBuilder object from the connection string, and sets the EntityPath.
// Typically, the connection string should have the entity path in it, but this simple scenario
// uses the connection string from the namespace.
var connectionStringBuilder = new EventHubsConnectionStringBuilder(EhConnectionString)
{
EntityPath = EhEntityPath
};
eventHubClient = EventHubClient.CreateFromConnectionString(connectionStringBuilder.ToString());
var json = File.ReadAllText(#"D:\Sample.json");
var eventData = new EventData(Encoding.UTF8.GetBytes(json));
await eventHubClient.SendAsync(eventData);
await eventHubClient.CloseAsync();
Console.WriteLine("Press ENTER to exit.");
Console.ReadLine();
}
}
}
Wrap your events into a JSON array:
using (var ms = new MemoryStream())
using (var sw = new StreamWriter(ms))
{
// Wrap events into JSON array:
sw.Write("[");
for (int i = 0; i < events.Count; ++i)
{
if (i > 0)
{
sw.Write(',');
}
sw.Write(events[i]);
}
sw.Write("]");
sw.Flush();
ms.Position = 0;
// Send JSON to event hub.
EventData eventData = new EventData(ms);
eventHubClient.Send(eventData);
}
Reference: learn.microsoft.com/time-series-insights-send-events
I'm sure you have figured this out by now but you're problem is not with JSON, it's with how you're using the event hub client.
Instead of this line:
await EventHubClient.SendAsync(eventData);
it should be this:
await client.SendAsync(eventData);
JSON is just a string for Event Hubs, so as simple as
var json = File.ReadAllText("myfile.json");
var eventData = new EventData(Encoding.UTF8.GetBytes(json));
await eventHubClient.SendAsync(eventData);

C# Windows Service - this keyword error

I have the following code which works fine when I use it within a Windows Forms application, however the application I'm writing needs to run as a Windows service, and when I moved my code into the Windows Service template in Visual Studio 2015 Community Edition, I get the following error.
Cannot implicitly convert type "MyWindowsService.Main" to "System.ComponentModel.ISynchronizeVoke". An explicit conversion exists (are you missing a cast?)
Could anyone shed some light on why I am getting this error, and what I need to do to resolve it?
The code which throws the error is the line below, and it is located within the OnStart method of my main class (named Main.cs). The code is used to create an instance of the DataSubscriber class (AdvancedHMI library).
dataSubscribers[dataSubscriberIndex].SynchronizingObject = this;
It has to have something to do with the fact that the code is in a Windows service template, because using this works perfectly in my forms application running the same code.
UPDATE
Correction, I've attempted to cast this to the required type, and now get the following error on run.
Additional information: Unable to cast object of type 'MyWindowsService.Main' to type 'System.ComponentModel.ISynchronizeInvoke'.
Code:
dataSubscribers[dataSubscriberIndex].SynchronizingObject = (System.ComponentModel.ISynchronizeInvoke)this;
UPDATE
I've included the entire contents of the Main.cs file from my Windows Service application.
using System.Data;
using System.Diagnostics;
using System.Linq;
using System.ServiceProcess;
using System.Text;
using System.Threading.Tasks;
using MySql.Data.MySqlClient;
using AdvancedHMIDrivers;
using AdvancedHMIControls;
using MfgControl.AdvancedHMI.Drivers;
using MfgControl.AdvancedHMI.Controls;
using System.Collections.ObjectModel;
namespace PLCHistoricDataHarvester {
public partial class Main : ServiceBase {
private EthernetIPforCLXCom commObject = new EthernetIPforCLXCom();
private globals globals = new globals();
private Dictionary<String, String> operationLines = new Dictionary<String, String>();
private Dictionary<String, String> tags = new Dictionary<String, String>();
private Collection<DataSubscriber> dataSubscribers = new Collection<DataSubscriber>();
private int harvesterQueueCount = 0;
private string harvesterInsertValues = String.Empty;
public Main() {
InitializeComponent();
}
protected override void OnStart(string[] args) {
// Initialize our harvester program
initializeHarvester();
Console.WriteLine("The program has started");
}
protected override void OnStop() {
// Call code when the service is stopped
Console.WriteLine("Program has stopped");
Console.ReadLine();
}
public void initializeHarvester() {
// First, we connect to the database using our global connection object
globals.dbConn.DatabaseName = "operations";
if (!globals.dbConn.IsConnect()) {
// TODO: Unable to connect to database. What do we do?
}
// Second, we connect to the database and pull data from the settings table
globals.initializeSettingsMain();
// Set IP address of PLC
commObject.IPAddress = globals.getSettingsMain("Processor_IP");
// Pull distinct count of our parent tags (Machines ex: Line 1, etc)
operationLines = globals.getOperationLines();
// If we have at least 1 operation line defined...we continue
if (operationLines.Keys.Count > 0) {
//Now we loop over the operation lines, and pull back the data points
int dataSubscriberIndex = 0;
foreach (KeyValuePair<String, String> lines in operationLines) {
int line_id = int.Parse(lines.Key);
string name = lines.Value;
tags = globals.getTags(line_id);
// If we have at least 1 tag for this operation line, we continue...
if (tags.Keys.Count > 0 && tags["tags"].ToString().IndexOf(",") != -1) {
// Create our dataSubscriber object
dataSubscribers.Add(new DataSubscriber());
dataSubscribers[dataSubscriberIndex].SynchronizingObject = (ISynchronizeInvoke)this;
dataSubscribers[dataSubscriberIndex].CommComponent = commObject;
dataSubscribers[dataSubscriberIndex].PollRate = 1000;
dataSubscribers[dataSubscriberIndex].PLCAddressValue = tags["tags"];
dataSubscribers[dataSubscriberIndex].DataChanged += new EventHandler<MfgControl.AdvancedHMI.Drivers.Common.PlcComEventArgs>(subscribeCallback);
// Increment our dataSubscriberIndex
dataSubscriberIndex++;
}
}
}
}
private void subscribeCallback(object sender, MfgControl.AdvancedHMI.Drivers.Common.PlcComEventArgs e) {
// code removed as it is irrelevant
}
}
}
The error message says this:
An explicit conversion exists (are you missing a cast?)
So add a cast like this:
dataSubscribers[dataSubscriberIndex].SynchronizingObject = (ISynchronizeInvoke)this;
^^^^^^^^^^^^^^^^^^^^
//Add this
If you've got a console app, the easiest way to convert it to a windows service is by using Topshelf, a nuget package which lets you run in either console mode or nt service mode.
Here's the quickstart guide.
We use it to write services all the time and it helps you avoid this kind of fragile shenanigans.

How do I execute a script with Roslyn in End User Preview

I'm trying to play around with the end user preview of roslyn and would like to execute a simple script. What I would like to do is something like:
static void Main(string[] args)
{
// Is this even valid?
var myScript = "int x = 5; int y = 6; x + y;";
// What should I do here?
var compiledScript = Something.Compile(myScript);
var result = compiledScript.Execute(myScript);
Console.WriteLine(result);
}
Can someone point to some resources and/or tell me which nuget packages to install to make this happen. I've installed the Microsoft.CodeAnalysis, but can't figure out if it doable with just that, I feel like I'm missing something.
The scripting APIs which would allow you to do this very easily were (temporarily) removed in the latest preview. You can still compile a script, emit and load the assembly and invoke its entry point by doing something along the lines of
public static class Program
{
public static void Main(string[] args)
{
var assemblyPath = Path.GetDirectoryName(typeof(object).Assembly.Location);
var defaultReferences = new[] { "mscorlib.dll", "System.dll", "System.Core.dll" };
var script = #"using System;
public static class Program
{
public static void Main(string[] args)
{
Console.WriteLine(""Hello {0}"", args[0]);
}
}";
// Parse the script to a SyntaxTree
var syntaxTree = CSharpSyntaxTree.ParseText(script);
// Compile the SyntaxTree to a CSharpCompilation
var compilation = CSharpCompilation.Create("Script",
new[] { syntaxTree },
defaultReferences.Select(x => new MetadataFileReference(Path.Combine(assemblyPath, x))),
new CSharpCompilationOptions(OutputKind.ConsoleApplication));
using (var outputStream = new MemoryStream())
using (var pdbStream = new MemoryStream())
{
// Emit assembly to streams.
var result = compilation.Emit(outputStream, pdbStream: pdbStream);
if (!result.Success)
{
return;
}
// Load the emitted assembly.
var assembly = Assembly.Load(outputStream.ToArray(), pdbStream.ToArray());
// Invoke the entry point.
assembly.EntryPoint.Invoke(null, new object[] { new[] { "Tomas" } });
}
}
}
It will output Hello Tomas in the console :)
It appears that in the April 2014 release, scripting has been temporarily removed:
What happened to the REPL and hosting scripting APIs?
The team is reviewing the designs of these components that you saw in
previous CTPs, before re-introducing the components again. Currently
the team is working on completing the language semantics of
interactive/script code.

unhandled exception c# dll

I tring to test a new dll that I've build for c#
private void button1_Click(object sender, EventArgs e)
{
String [] first = UserQuery.Get_All_Users();
//MessageBox.Show(first);
}
but I get the following error at String [] first = UserQuery.Get_All_Users();
An unhandled exception of type 'System.NullReferenceException' occurred in User_Query.dll
Additional information: Object reference not set to an instance of an object.
I been tring to figure this one out for hours but can't find any null varibles
I post my dll in case the dll is wrong
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.DirectoryServices;
namespace User_Query
{
public class UserQuery
{
public static string[] Get_All_Users()
{
string[] names = new string[10];
var path = string.Format("WinNT://{0},computer", Environment.MachineName);
using (var computerEntry = new DirectoryEntry(path))
{
var userNames = from DirectoryEntry childEntry in computerEntry.Children
where childEntry.SchemaClassName == "User"
select childEntry.Name;
byte i = 0;
foreach (var name in userNames)
{
Console.WriteLine(name);
names[i] = name;
i++;
}
return names;
}
}
}
}
There is a problem with your. path variable... since there should be \\ instead of //
The problem here turned out not to be the code but be VS2010 not loading the dll. This happen because I decided to change the program from using the dll from the debug to the release version but I did not clean the project after doing it and therefore the program was not correctly loading the dll. All that need to be done was clean the project

Categories

Resources