Continue to Site

Eng-Tips is the largest engineering community on the Internet

Intelligent Work Forums for Engineering Professionals

  • Congratulations waross on being selected by the Eng-Tips community for having the most helpful posts in the forums last week. Way to Go!

Constrain Assemblies through .NET

Status
Not open for further replies.

lharrison

New member
Oct 19, 2011
52
I've written a c# program that allows me to import a number of parts simultaneously into a new assembly. Obviously they are in the correct locations, and I was wondering if there is a way to allow for user selection of edges in order to constrain the items.

Ideally this would be through the .NET interface.
 
Replies continue below

Recommended for you

This code gets me a generic ObjectSelect with the same dialog as the IDENT grip command, though I am not sure how to specify only edges and faces.

NXObject NO = null;
Point3d P3d = new Point3d();
UISession.SelectionManager.SelectObject("Select object", "select", Selection.SelectionScope.AnyInAssembly, true, true, out NO, out P3d);


Also, would anyone be willing to collaborate on some sort of C#/VB.net library of NXOpen functions? The lack of information is staggering!
 
This is what I managed to cobble together. It brings up the select objects dialog, but it seems that my masks are not working, and I can only highlight the part body of the basepart, and not any other objects.

//Object to be returned with selected objects
NXObject[] NO = null;

//Define Specific masks
Selection.MaskTriple Mask1 = new Selection.MaskTriple();
Mask1.Type = UFConstants.UF_solid_body_subtype;
Mask1.Subtype = 0;
Mask1.SolidBodySubtype = UFConstants.UF_UI_SEL_FEATURE_ANY_EDGE;

Selection.MaskTriple Mask2 = new Selection.MaskTriple();
Mask2.Type = UFConstants.UF_solid_body_subtype;
Mask2.Subtype = 0;
Mask2.SolidBodySubtype = UFConstants.UF_UI_SEL_FEATURE_ANY_FACE;

//Add masks to the masktriple collection of masks
Selection.MaskTriple[] MaskCollection = { Mask1, Mask2 };


UISession.SelectionManager.SelectObjects("Select Faces To Mate", "Select 2 Faces",Selection.SelectionScope.AnyInAssembly,Selection.SelectionAction.ClearAndEnableSpecific,true,true,MaskCollection,out NO);
 
If you can convert VB to C#, this may be of some use to you. I don't claim it is the best way or only way to accomplish this.

There are some examples in the <NX folder>\UGOPEN\SampleNXOpenApplications\.NET folder. Also, if your maintenance fees are up to date you can access GTAC online where they have several .NET examples.

Code:
Option Strict Off
Imports System
Imports System.Collections
Imports NXOpen
Imports NXOpen.UF

Module NXJournal
Sub Main

Dim theSession As Session = Session.GetSession()
Dim workPart As Part = theSession.Parts.Work
Dim displayPart As Part = theSession.Parts.Display

Dim lw As ListingWindow = theSession.ListingWindow
Dim mySelections() as NXObject
Dim myFaces as New ArrayList()
Dim myEdges as New ArrayList()
Dim i as Integer
Dim myFace as Face
Dim myEdge as Edge

		If (SelectFaces(mySelections) = Selection.Response.Ok) Then
			lw.Open
			lw.WriteLine(UBound(mySelections) + 1 & " faces/edges selected")
			For each myEntity as NXObject in mySelections
				'lw.WriteLine(myEntity.GetType().ToString)
				if myEntity.GetType().ToString = "NXOpen.Face" then
					myFaces.Add(myEntity)
				elseif myEntity.GetType().ToString = "NXOpen.Edge" then
					myEdges.Add(myEntity)
				end if
			Next
			lw.WriteLine("myFaces.Count = " & myFaces.Count)
			lw.WriteLine("myEdges.Count = " & myEdges.Count)
			lw.WriteLine("")
			For Each myFace in myFaces
				lw.WriteLine("Face color: " & myFace.Color)
			Next
			lw.WriteLine("")
			For Each myEdge in myEdges
				lw.WriteLine("Edge Layer: " & myEdge.Layer)
			Next
		Else
			lw.Open
			lw.WriteLine("Selection cancelled")
			lw.WriteLine("")
			lw.Close
		End If

End Sub


Function SelectFaces(ByRef selectedObjects() As NXObject) As Selection.Response

	Dim ui As UI = NXOpen.UI.GetUI
	Dim message As String = "Select Faces"
	Dim title As String = "Selection"
	
	Dim scope As Selection.SelectionScope = Selection.SelectionScope.AnyInAssembly
	Dim keepHighlighted As Boolean = False
	Dim includeFeatures As Boolean = False
	Dim resp As Selection.Response
	
	Dim selectionAction As Selection.SelectionAction = Selection.SelectionAction.ClearAndEnableSpecific
	
	Dim selectionMask_array(1) As Selection.MaskTriple
	With selectionMask_array(0)
		.Type = UFConstants.UF_solid_type
		.Subtype = 0
		.SolidBodySubtype = UFConstants.UF_UI_SEL_FEATURE_ANY_FACE
	End With
	With selectionMask_array(1)
		.Type = UFConstants.UF_solid_type
		.Subtype = UFConstants.UF_solid_body_subtype
		.SolidBodySubtype = UFConstants.UF_UI_SEL_FEATURE_ANY_EDGE
	End With
	
	resp = ui.SelectionManager.SelectObjects(message, title, scope, selectionAction, includeFeatures, keepHighlighted, selectionMask_array, selectedObjects)
	
	Return resp
	
End Function
	
End Module
 
Thank you for the response! I actually figured it out earlier today, and it is a near copy of the code you posted above.

A few things to note:
I am loading parts initially, and BaseParts cannot easily selected by features such as edges. You must create a blank part, then add your base feature as a component(as you should do anyway).

I also coded a way to select circular features and constrain them concentrically, all from .NET. I'll post the code once I get a few of the smaller kinks out of it.
 
Here's the code to constrain to objects together concentrically. You need to know which objects youre starting with, since the CreateConstraints method needs basepart and component arguments passed to it.

It could be recoded but this is just a rip of what I am using.


Code:
//C# 
//Bruce Harrison
//12-21-2011

using NXOpen.Assemblies;
using NXOpen.Positioning;
using NXOpenUI;
using NXOpen.UF;

        /// <summary>
        /// Overly complex method for constraining objects!
        /// </summary>
        /// <param name="Component1">Newest part to be added to assembly</param>
        /// <param name="basePart1">Assembly that will be added to</param>
        public void CreateConstraints(Component Component1, BasePart basePart1)
        {

            Session MainSession = Session.GetSession();
            UI UISession = UI.GetUI();
            Part WorkPart = null;

            //Object array that will save the selected objects
            NXObject[] NO = null;

            WorkPart = MainSession.Parts.Work;
            WorkPart.Views.WorkView.RenderingStyle = NXOpen.View.RenderingStyleType.ShadedWithEdges;

            //Masks that define what is selectable
            var MaskCollection = CreateMask();

            ComponentPositioner CP1 = WorkPart.ComponentAssembly.Positioner;
            CP1.ClearNetwork();

            Arrangement Arrangement1 = (Arrangement)WorkPart.ComponentAssembly.Arrangements.FindObject("Arrangement 1");
            CP1.PrimaryArrangement = Arrangement1;
            CP1.BeginAssemblyConstraints();

            MainSession.Preferences.Assemblies.InterpartPositioning = true;

            Network Network1 = CP1.EstablishNetwork();

            ComponentNetwork CN1 = (ComponentNetwork)Network1;
            CN1.DisplayComponent = null;
            CN1.NetworkArrangementsMode = ComponentNetwork.ArrangementsMode.Existing;
            CN1.MoveObjectsState = true;

            //Startup the object selector dialog. need to find a way to limit selection to 2 edges.
            UISession.SelectionManager.SelectObjects("Select 2 Circular Edges To Join", "Select 2 Edges", Selection.SelectionScope.AnyInAssembly, Selection.SelectionAction.ClearAndEnableSpecific, true,false, MaskCollection, out NO);
            Constraint Constraint1 = CP1.CreateConstraint();

            ComponentConstraint CConstraint1 = (ComponentConstraint)Constraint1;
            Constraint1.ConstraintType = Constraint.Type.Concentric;

            //Begin constraint on first edge
            Edge Face1 = (Edge)NO[0];
            var Constraint1Ref = CConstraint1.CreateConstraintReference(Component1, Face1, false, false, false);
            //Make this edge stationary, the second will move to meet this one
            Constraint1Ref.SetFixHint(true);

            //Define constraint edge on second surface
            Edge Face2 = (Edge)NO[1];
            var Constraint2Ref = CConstraint1.CreateConstraintReference(basePart1, Face2, false, false, false);

            //flip constraint 180
            CConstraint1.FlipAlignment();

            //compute constraints
            CN1.Solve();

            //If part is 180 off, this message box give you the option of flipping it. Need to find a way to see if one part is
            //colliding with another to automate this.
            var Response = MessageBox.Show("Reverse direction of constraint?", "Reverse Constraint?", MessageBoxButtons.YesNo, MessageBoxIcon.Question);
            if (Response == DialogResult.Yes)
            {
                CConstraint1.FlipAlignment();
                CN1.Solve();
            }

            //throw away all the extra junk
            CP1.ClearNetwork();
            CP1.DeleteNonPersistentConstraints();
            CP1.EndAssemblyConstraints();
        }

        /// <summary>
        /// Setup the masks required for manual selection
        /// </summary>
        /// <returns>Collection of MaskTriple(s)</returns>
        private Selection.MaskTriple[] CreateMask()
        {
            var Mask1 = new Selection.MaskTriple();
            Mask1.Type = UFConstants.UF_solid_type;
            Mask1.Subtype = UFConstants.UF_solid_body_subtype;
            Mask1.SolidBodySubtype = UFConstants.UF_UI_SEL_FEATURE_ANY_EDGE;

            //Add masks to the masktriple collection of masks
            Selection.MaskTriple[] MaskCollection = { Mask1 };

            return MaskCollection;
        }
 
I am new to NX open programming.
I have written a program in VB.NET to assemble components using
assembly constraints.
However when i try to run the program , even though all the assembly
constraints gets created successfully and their constraint solver
status as "Solved", Still the parts are distanced apart and they are
not mating.
Any Idea on what i am missing in my code?

I have developed the code mainly by recording journal in NX6.0
 
I haven't done much work automating constraints, but I'd be willing to take a look if you post your code. If you have a small simplified assembly that you are testing with you should provide that as well, or at least instructions on how to recreate it.
 
I see you started a new thread, I'll move it over to there.
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor