I am working with convergent facet bodies in NX and using C# in NXOpen. In the process, I am using UFSession.Facet.AskAdjacentFacet function to get the adjacent facets of each facet. But on using this particular command, the NXOpen throws error stating "NXOpen.NXException: The facet object is not supported for this operation". I went through the example given in NXOpen documentation (https://docs.plm.automation.siemens.com/data_services/resources/nx/10/nx_api/en_US/custom/ugopen_doc/uf_facet/uf_facet_eg2.c) and used similar approach, but this error shows up any way. Below is the script that I tried.
'''
public static void Main(string[] args)
{
NXOpen.UF.UFFacet myFacet = UFSession.Facet;
int facetID;
int edgeID;
int adjFacID;
int edgeIDinAdjFac;
int null_facet_ID = UFConstants.UF_FACET_NULL_FACET_ID;
facetID = null_facet_ID;
foreach (NXOpen.Facet.FacetedBody facetBody in workPart.FacetedBodies)
{
myFacet.CycleFacets(facetBody.Tag, ref facetID); // initialise for cycling
while (facetID != null_facet_ID)
{
List<int> Adj_fac_list = new List<int>();
for (edgeID = 0; edgeID < 3; edgeID++)
{
myFacet.AskAdjacentFacet(facetBody.Tag, facetID, edgeID, out adjFacID, out edgeIDinAdjFac);
if (adjFacID != UFConstants.UF_FACET_NULL_FACET_ID)
{
Adj_fac_list.Add(adjFacID);
}
}
}
}
}
Note: I could use the same model tag and facet id in the function UFSession.FACET.AskNumVertsInFacet and the script works fine. But I do not know why AskAdjacentFacet is not working. Can anyone help me on why there is an error and how to get this working?
On first glimpse, the problem I see is that you have not initialized the variable myFacet and it's null. And since it's null, you cannot call its members.
So change a single line of the code from
NXOpen.UF.UFFacet myFacet = UFSession.Facet;
To
NXOpen.UF.UFFacet myFacet = UFSession.GetUFSession().Facet;
Related
Since P/Invoke does not support returning dynamic sized arrays (you must statically specify the size of the array at compile time), I decided to write a C++/CLI wrapper for some functions I need in a .net application that is otherwise written in C#.
Take the GetTcpTable2 function from IpHlpApi.dll...
I made C# classes to match the types in that function as follows:
public class MibTcpTable2
{
public int NumEntries;
public MibTcpRow2[] Table;
}
public class MibTcpRow2
{
public int State;
public int LocalAddr;
public int LocalPort;
public int RemoteAddr;
public int RemotePort;
public int OwningPid;
public int OffloadState;
}
In my C++/CLI program, I call GetTcpTable2 as shown in the MSDN example, and then iterate through the resulting array and assign its output to a new instance of the TcpTable2 class I made in C#.
See code:
PMIB_TCPTABLE2 pTcpTable;
ULONG ulSize = 0;
DWORD dwRetVal = 0;
pTcpTable = (MIB_TCPTABLE2 *)MALLOC(sizeof(MIB_TCPTABLE2));
if (pTcpTable == NULL) {
return nullptr;
}
ulSize = sizeof(MIB_TCPTABLE);
if ((dwRetVal = ::GetTcpTable2(pTcpTable, &ulSize, TRUE)) == ERROR_INSUFFICIENT_BUFFER)
{
FREE(pTcpTable);
pTcpTable = (MIB_TCPTABLE2 *)MALLOC(ulSize);
if (pTcpTable == NULL) {
return nullptr;
}
}
NetClasses::MibTcpTable2^ managedTable = gcnew NetClasses::MibTcpTable2();
managedTable->Table = gcnew cli::array<NetClasses::MibTcpRow2^>(pTcpTable->dwNumEntries);
if ((dwRetVal = ::GetTcpTable2(pTcpTable, &ulSize, TRUE)) == NO_ERROR)
{
for (int i = 0; i < pTcpTable->dwNumEntries; i++)
{
managedTable->Table[i].LocalAddr = pTcpTable->table[i].dwLocalAddr;
managedTable->Table[i].LocalPort = pTcpTable->table[i].dwLocalPort;
managedTable->Table[i].OffloadState = pTcpTable->table[i].dwOffloadState;
managedTable->Table[i].OwningPid = pTcpTable->table[i].dwOwningPid;
managedTable->Table[i].RemoteAddr = pTcpTable->table[i].dwRemoteAddr;
managedTable->Table[i].RemotePort = pTcpTable->table[i].dwRemotePort;
managedTable->Table[i].State = pTcpTable->table[i].dwState;
}
}
However, Visual Studio 2015 hates the accesses to managedTable inside the for loop. It complains that "expression must have a class type." Ok, so that usually means you're using the wrong data accessor operator, so I tried a dot instead. No dice.
How the heck do I access the Table member of managedTable? The access to it before the for loop was valid. Why isn't it valid inside the for loop?
Your array access is giving you a handle to a managed object, so shouldn't your field access also be -> rather than . ?
Array[i]->Field
I'm starting to dive into the world of C# Dynamics and Metaprogramming, and having some trouble.
I managed to create a CodeDom tree, and generate the following code:
namespace Mimsy {
using System;
using System.Text;
using System.Collections;
internal class JubJub {
private int _wabeCount;
private ArrayList _updates;
public JubJub(int wabeCount) {
this._updates = new ArrayList();
this.WabeCount = wabeCount;
}
public int WabeCount {
get {
return this._wabeCount;
}
set {
if((value < 0))
this._wabeCount = 0;
else
this._wabeCount = value;
this._updates.Add(this._wabeCount);
}
}
public string GetWabeCountHistory() {
StringBuilder result = new StringBuilder();
int ndx;
for(ndx = 0; (ndx < this._updates.Count); ndx = ndx + 1) {
if((ndx == 0))
result.AppendFormat("{0}", this._updates[ndx]);
else
result.AppendFormat(", {0}", this._updates[ndx]);
}
}
}
}
I am then compiling dynamically this namespace to an assembly named "dummy".
I can succesfully get an instance of this Type:
string typeName = "Mimsy.JubJub";
Type type = dummyAssembly.GetType(typeName);
dynamic obj = Activator.CreateInstance(type, new object[] { 8 });
//obj is a valid instance type
If I debug this code, I can see in the debugger that obj actually has the property WabeCount:
However, when trying to access this property, the compiler shouts that the dynamic property does not exist.
There are one or perhaps two problems with your code:
You are using an internal class, and trying to access it with dynamic. The two things don't play well together. See https://stackoverflow.com/a/18806787/613130. Use public clasas
You need to cast the value before assigning it to wabeCount, like:
obj.WabeCount = (int)wabes[ndx]
Note that technically, if your "main" assembly is strong named, you could add the InternalsVisibleToAttribute to the "dynamic" assembly to make its internal "things" visible to the main assembly... I do think it would be wasted work.
I have the following code
class Card
{
string name;
public string Name
{
get { return name; }
set { name = value; }
}
}
class Program
{
static void Main(string[] args)
{
int KaLP = 8000;
int YuLP = 8000;
Card bewd = new Card();
Card LOD = new Card();
var KaibaDeck = new List<Card>() { bewd, LOD };
var KaibaHand = new List<Card>() { };
var KaibaFusionDeck = new List<Card>() { };
var KaibaGraveyard = new List<Card>() { };
var YugiDeck = new List<Card>() { };
var YugiHand = new List<Card>() { };
var YugiFusionDeck = new List<Card>() { };
var YugiGraveyard = new List<Card>() { };
int KaibaDeckSize = KaibaDeck.Count;
string sDrawChoice;
int DrawChoice;
while (KaibaDeckSize > 0)
{
if (DrawChoice == 0)
{
break;
}
else
{
KaibaBattlePhase(KaibaHand, KaibaDeck, KaibaFusionDeck, YugiDeck, Field, KaibaGraveyard, YugiGraveyard, KaLP, YuLP, "Battle");
}
}
}
public static void KaibaBattlePhase(List<Card> KaibaHand, List<Card> KaibaDeck, List<Card> KaibaFusionDeck, List<Card> YugiDeck, List< List<Card> > Field, List<Card> KaibaGraveyard, List<Card> YugiGraveyard, int KaLP, int YuLP, const string Phase)
{
string sDecision;
int Decision;
while(true)//so the while loop NEVER breaks unless you have a 'break' later on
{
Console.WriteLine("Would you like to continue the Battle Phase? (Yes-'1' No-'0', Check Kaiba's Graveyard '-1', Check YUGI's graveyard '-2')");
sDecision = Console.ReadLine();
int.TryParse(sDecision, out Decision);
if (Decision==0)
{
break;
}
if (Decision==-1)
{
KaibaGraveyardFunction(KaibaGraveyard);
}
}
}
public static void KaibaGraveyardFunction(List<Card> KaibaGraveyard)
{
Console.WriteLine("Kaiba's graveyard contains: ");
foreach (Card KG in KaibaGraveyard)
{
Console.WriteLine(KG.Name);
}
}
}
I'm getting the following errors:
On the line KaibaGraveyardFunction(KaibaGraveyard);:
Method must have a return type
At while(true):
Invalid token 'while' in class, struct, or interface member declaration
In addition, I'm getting alot of other errors such as
"Invalid token '(', '=', '.' in class, struct, or interface member declaration"
"Syntax error, ']' expected"
At the end of your method declaration for KaibaBattlePhase you have this method parameter:
const string Phase
That's a syntax error which is confusing the compiler and causing it to not understand pretty much anything afterward. (I've never seen it get that confused from a keyword, usually that happens with missing/extra curly braces and such. But I guess this triggers it too.)
Why are you trying to pass a constant as a method parameter? That doesn't really make a lot of sense. If the method thinks it's a constant, it won't accept any value for it. If you pass it a constant, the method wouldn't know or care where the value came from.
If you remove const then the rest of the errors go away.
(Side note: The error becomes a lot easier to see if you clean up that method declaration. 10 parameters is a lot. It's highly likely that you can get away with some refactoring there to make it a lot cleaner. At its simplest, you can replace all of those parameters with a parameter DTO object which has those as properties. Potentially more useful would be the Replace Method With Method Object pattern, illustrated here.)
Not completely following your logic and not sure this is your issue but you never reevaluate KaibaDeckSize. If your intention is to simply use the while (KaibaDeckSize > 0) {} evaluation as a condition of entering the block, consider replacing it with a simple if statement: if (KaibaDeckSize > 0) {} Also, you never initialize DrawChoice which will generate a Use of unassigned local variable error during compilation. Use: int DrawChoice = 0; And this DrawCount` is never reassigned either.
Did you actually post your most recent code?
int KaibaDeckSize = KaibaDeck.Count;
string sDrawChoice;
int DrawChoice = 0;
while (KaibaDeckSize > 0)
{
if (DrawChoice == 0)
{
break;
}
else
{
KaibaBattlePhase(KaibaHand, KaibaDeck,
KaibaFusionDeck, YugiDeck, Field,
KaibaGraveyard, YugiGraveyard, KaLP, YuLP, "Battle");
}
KaibaDeckSize = KaibaDeck.Count;
}
I've been looking at some code in a debugger associated with Razor View engine and I noticed that some of the types appear in Debugger with a trailing dot character at the end of the type name e.g.:
{Nancy.ViewEngines.Razor.RazorViewEngine.}
Does anyone know what this indicates? It's not valid syntax to use it when specifying a cast on an object so I'm intrigued as to what it indicates within the debugger.
EDIT: As requested by #Damien_The_Unbeliever, screenshot of the variable in debugger:
And the code that I'm looking at:
public TCompiledView GetOrAdd<TCompiledView>(
ViewLocationResult viewLocationResult, Func<ViewLocationResult, TCompiledView> valueFactory)
{
TCompiledView compiledView = default(TCompiledView);
compiledView = (TCompiledView)this.cache.GetOrAdd(viewLocationResult, x => valueFactory(x));
To give a little more background, we're trying to add logging to our Nancy View Cache to investigate an intermittent issue with Razor Views throwing compilation errors, but that isn't really relevant to the question.
I've seen this happen when the variable/value is actually of a compiler generated type (e.g. for holding the "local variables" captured by a lambda, async, iterator, etc). The debugger (in various places) seems unable to display the actual class name.
E.g. this example program:
class Program
{
static void Main(string[] args)
{
var p = new Program();
p.DoStuff();
}
void DoStuff()
{
int i = 19;
Expression<Func<int>> j = () => i + 10;
var k = (((j.Body as BinaryExpression).Left as MemberExpression).Expression as ConstantExpression).Value;
Console.ReadLine();
}
}
With a breakpoint on Console.ReadLine(), you'll find the k class's type looks like Program. rather than Program+<>_DisplayClass0
Addition by Jeppe: This example is a slight simplification of the above, avoiding the expression tree. Looks at a delegate instance's Target which will be an instance of a generated class. For comparison also looks at an iterator block type:
using System;
using System.Collections.Generic;
static class Program
{
static void Main()
{
int i = 19; // to be captured by lambda, will become field on a generated class
Func<int> f = () => i;
var target = f.Target; // when debugging type looks like "Program."
Console.WriteLine(target.GetType().ToString()); // writes "Program+<>c__DisplayClass1"
var seq = GetSeq(); // when debugging type looks like "Program.GetSeq"
Console.WriteLine(seq.GetType().ToString()); // writes "Program+<GetSeq>d__3"
}
static IEnumerable<int> GetSeq() // returns "state machine" (iterator block)
{
yield return 42;
}
}
I'm trying to use Weka in my C# application. I've used IKVM to bring the Java parts into my .NET application. This seems to be working quite well. However, I am at a loss when it comes to Weka's API. How exactly do I classify instances if they are programmatically passed around in my application and not available as ARFF files.
Basically, I am trying to integrate a simple co-reference analysis using Weka's classifiers. I've built the classification model in Weka directly and saved it to disk, from where my .NET application opens it and uses the IKVM port of Weka to predict the class value.
Here is what I've got so far:
// This is the "entry" method for the classification method
public IEnumerable<AttributedTokenDecorator> Execute(IEnumerable<TokenPair> items)
{
TokenPair[] pairs = items.ToArray();
Classifier model = ReadModel(); // reads the Weka generated model
FastVector fv = CreateFastVector(pairs);
Instances instances = new Instances("licora", fv, pairs.Length);
CreateInstances(instances, pairs);
for(int i = 0; i < instances.numInstances(); i++)
{
Instance instance = instances.instance(i);
double classification = model.classifyInstance(instance); // array index out of bounds?
if(AsBoolean(classification))
MakeCoreferent(pairs[i]);
}
throw new NotImplementedException(); // TODO
}
// This is a helper method to create instances from the internal model files
private static void CreateInstances(Instances instances, IEnumerable<TokenPair> pairs)
{
instances.setClassIndex(instances.numAttributes() - 1);
foreach(var pair in pairs)
{
var instance = new Instance(instances.numAttributes());
instance.setDataset(instances);
for (int i = 0; i < instances.numAttributes(); i++)
{
var attribute = instances.attribute(i);
if (pair.Features.ContainsKey(attribute.name()) && pair.Features[attribute.name()] != null)
{
var value = pair.Features[attribute.name()];
if (attribute.isNumeric()) instance.setValue(attribute, Convert.ToDouble(value));
else instance.setValue(attribute, value.ToString());
}
else
{
instance.setMissing(attribute);
}
}
//instance.setClassMissing();
instances.add(instance);
}
}
// This creates the data set's attributes vector
private FastVector CreateFastVector(TokenPair[] pairs)
{
var fv = new FastVector();
foreach (var attribute in _features)
{
Attribute att;
if (attribute.Type.Equals(ArffType.Nominal))
{
var values = new FastVector();
ExtractValues(values, pairs, attribute.FeatureName);
att = new Attribute(attribute.FeatureName, values);
}
else
att = new Attribute(attribute.FeatureName);
fv.addElement(att);
}
{
var classValues = new FastVector(2);
classValues.addElement("0");
classValues.addElement("1");
var classAttribute = new Attribute("isCoref", classValues);
fv.addElement(classAttribute);
}
return fv;
}
// This extracts observed values for nominal attributes
private static void ExtractValues(FastVector values, IEnumerable<TokenPair> pairs, string featureName)
{
var strings = (from x in pairs
where x.Features.ContainsKey(featureName) && x.Features[featureName] != null
select x.Features[featureName].ToString())
.Distinct().ToArray();
foreach (var s in strings)
values.addElement(s);
}
private Classifier ReadModel()
{
return (Classifier) SerializationHelper.read(_model);
}
private static bool AsBoolean(double classifyInstance)
{
return classifyInstance >= 0.5;
}
For some reason, Weka throws an IndexOutOfRangeException when I call model.classifyInstance(instance). I have no idea why, nor can I come up with an idea how to rectify this issue.
I am hoping someone might know where I went wrong. The only documentation for Weka I found relies on ARFF files for prediction, and I don't really want to go there.
For some odd reason, this exception was raised by the DTNB classifier (I was using three in a majority vote classification model). Apparently, not using DTNB "fixed" the issue.