Showing results for 
Search instead for 
Do you mean 
Reply
Solved! Go to solution

WAVE Linked Curves in Incorrect Locations

I've come across an issue with WAVE linking curves from one component to another programatically. What happens is that the wave-linked curves are not in the same location as the curves they were linked from. The difference between the desired location and the location they are created at is the same as the difference between the Absolute CSys of the Display Part and the Absolute CSys of the Work Part. Because of this I'm inclined to think that it gets the location for the curves from the display part but then recreates them on the Work Part's CSys, which places them at the incorrect location.

Below is my code, I created the code by generalizing code produced by a recording of the wave-linking process and it's nearly identical to the code provided here.

Please note that this does not occur when the curves are WAVE-linked by hand, only when they're moved by a program.

I've tried changing some elements of the CompositeCurveBuilder, such as MakePositionIndependent and InheritDisplayProperties to True or False in different combinations to no avail. If anyone has a fix or work around I'd love the help.

 

Private Function WavelinkCurves(ByVal targetComponent As Component, ByVal curves() As Curve) As CompositeCurve
	Dim oldWrk As Part = nxSes.Parts.Work
	cmpSetWrk(targetComponent)

	Dim wavLnkBldr As WaveLinkBuilder
	wavLnkBldr = nxSes.Parts.Work.BaseFeatures.CreateWaveLinkBuilder(Nothing)
	wavLnkBldr.Type = WaveLinkBuilder.Types.CurveLink
	Dim crvBldr As CompositeCurveBuilder
	crvBldr = wavLnkBldr.CompositeCurveBuilder
	crvBldr.AllowSelfIntersection = True
	crvBldr.Section.DistanceTolerance = 0.0001
	crvBldr.Section.ChainingTolerance = 0.000095
	crvBldr.Associative = True
	crvBldr.ParentPart = CompositeCurveBuilder.PartType.OtherPart
	crvBldr.MakePositionIndependent = False
	crvBldr.FixAtCurrentTimestamp = False
	crvBldr.HideOriginal = False
	crvBldr.InheritDisplayProperties = True
	crvBldr.JoinOption = CompositeCurveBuilder.JoinMethod.No
	crvBldr.Tolerance = 0.0001
	Dim section1 As Section
	section1 = crvBldr.Section
	section1.SetAllowedEntityTypes(Section.AllowTypes.CurvesAndPoints)
	section1.AllowSelfIntersection(True)

	For Each tmpCrv As Curve In curves
		Dim curveDumbRule1 As CurveDumbRule
		curveDumbRule1 = nxSes.Parts.Work.ScRuleFactory.CreateRuleCurveDumb({tmpCrv})
		Dim rules1() As SelectionIntentRule = {curveDumbRule1}

		section1.AddToSection(rules1, tmpCrv.Prototype, Nothing, Nothing, New Point3d(0.0, 0.0, 0.0), Section.Mode.Create, False)
	Next

	WavelinkCurves = wavLnkBldr.Commit()
	wavLnkBldr.Destroy()

	prtSetWrk(oldWrk)
End Function

 

 

11 REPLIES

Re: WAVE Linked Curves in Incorrect Locations

I've done something similar but used the ufs.Wave.CreateLinkedCurve function.

I found that if a component is re-positioned in an assy the resultant copy is moved back to it's absolute position (as if the component hadn't been moved in the assy).

 

with the ufs.Wave.CreateLinkedCurve function you can specify an xform.

Dim my_xform As Xform = thesession.Parts.Work.Xforms.CreateXform(root_comp, this_comp, SmartObject.UpdateOption.WithinModeling)

 

This fixed my issue and the resultant copies were located i nthe correct 3d space.

 

I can't see a similar option for the wavelinkbuilder you're using though.

Re: WAVE Linked Curves in Incorrect Locations

If you look at the old UF functions for wave linking they (almost) all need an XForm to be suppied. You could look at using the wrappers for these.

Graham Inchley Snr R&D Engineer (Systems Development), Sandvik Coromant
Lenovo ThinkPad W540, Win7, 16GB. Developing in: Java | C | C# | KF
Production: NX8.5.3.3 MP11 64bit Testing: NX9.0.2.5

Re: WAVE Linked Curves in Incorrect Locations

Here's some code that I have. In my (not so thorough) testing, it seems to give the same result as the interactive commands. Open your assembly and set your work part as desired before running the code. This is a simple example and only allows the selection of a single curve.

 

Option Strict Off
Imports System
Imports NXOpen
Imports NXOpen.UF

Module wavelink_curve

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

    Sub Main()

        Dim lw As ListingWindow = theSession.ListingWindow
        lw.Open()

        Dim markId1 As Session.UndoMarkId
        markId1 = theSession.SetUndoMark(Session.MarkVisibility.Visible, "wave link curve")

        Dim theCurve As Curve = Nothing
        If SelectCurve("Select a curve", theCurve) = Selection.Response.Cancel Then
            Return
        End If

        Dim curvePart As Part = Nothing
        If theCurve.IsOccurrence Then
            curvePart = theCurve.Prototype.OwningPart
        Else
            curvePart = theCurve.OwningPart
        End If

        If theSession.Parts.Work.Equals(curvePart) Then
            MsgBox("choose curve from a part other than the current work part")
            Return
        End If

        WaveLinkCurve(theCurve)

        lw.Close()

    End Sub

    Function SelectCurve(ByVal prompt As String, ByRef theObj As Curve) As Selection.Response

        Dim theUI As UI = UI.GetUI
        Dim title As String = "Select a curve"
        Dim includeFeatures As Boolean = False
        Dim keepHighlighted As Boolean = False
        Dim selAction As Selection.SelectionAction = Selection.SelectionAction.ClearAndEnableSpecific
        Dim cursor As Point3d
        Dim scope As Selection.SelectionScope = Selection.SelectionScope.AnyInAssembly
        Dim selectionMask_array(3) As Selection.MaskTriple
        Dim selObj As TaggedObject = Nothing

        With selectionMask_array(0)
            .Type = UFConstants.UF_circle_type
            .Subtype = 0
        End With
        With selectionMask_array(1)
            .Type = UFConstants.UF_conic_type
            .Subtype = UFConstants.UF_all_subtype
        End With
        With selectionMask_array(2)
            .Type = UFConstants.UF_line_type
            .Subtype = UFConstants.UF_all_subtype
        End With
        With selectionMask_array(3)
            .Type = UFConstants.UF_spline_type
            .Subtype = UFConstants.UF_all_subtype
        End With

        Dim resp As Selection.Response = theUI.SelectionManager.SelectTaggedObject(prompt, _
         title, scope, selAction, _
         includeFeatures, keepHighlighted, selectionMask_array, _
         selObj, cursor)

        theObj = selObj

        If resp = Selection.Response.ObjectSelected OrElse resp = Selection.Response.ObjectSelectedByName Then
            Return Selection.Response.Ok
        Else
            Return Selection.Response.Cancel
        End If

    End Function

    Sub WaveLinkCurve(ByVal someCurve As Curve)

        Dim waveLinkBuilder1 As Features.WaveLinkBuilder
        waveLinkBuilder1 = workPart.BaseFeatures.CreateWaveLinkBuilder(Nothing)

        Dim compositeCurveBuilder1 As Features.CompositeCurveBuilder
        compositeCurveBuilder1 = waveLinkBuilder1.CompositeCurveBuilder

        With compositeCurveBuilder1
            .AllowSelfIntersection = True
            .Section.DistanceTolerance = 0.001
            .Section.ChainingTolerance = 0.00095
            .Associative = True
            .MakePositionIndependent = False
            .FixAtCurrentTimestamp = False
            .HideOriginal = False
            .InheritDisplayProperties = False
            .JoinOption = Features.CompositeCurveBuilder.JoinMethod.No
            .Tolerance = 0.001
        End With

        Dim section1 As Section
        section1 = compositeCurveBuilder1.Section

        section1.SetAllowedEntityTypes(Section.AllowTypes.CurvesAndPoints)

        Dim curves1(0) As IBaseCurve
        curves1(0) = someCurve

        Dim curveDumbRule1 As CurveDumbRule
        curveDumbRule1 = workPart.ScRuleFactory.CreateRuleBaseCurveDumb(curves1)

        section1.AllowSelfIntersection(True)

        Dim rules1(0) As SelectionIntentRule
        rules1(0) = curveDumbRule1
        Dim nullNXObject As NXObject = Nothing

        Dim helpPoint1 As Point3d = New Point3d(0.0, 0.0, 0.0)
        section1.AddToSection(rules1, someCurve, nullNXObject, nullNXObject, helpPoint1, Section.Mode.Create, False)

        Dim nXObject1 As NXObject
        nXObject1 = waveLinkBuilder1.Commit()

        waveLinkBuilder1.Destroy()

    End Sub

End Module

Re: WAVE Linked Curves in Incorrect Locations

I tried your code as well as the method utilizing the base ufsession calls mentioned above. Your code works on the part when run as a stand-alone .vb file, however when put into the program it produces the same issue as with the code I had written before.

The clear differences between the two programs at this point are that my code is compiled as a .dll and also utilizes Block UI Styler for a front end. Is there any chance that either of these could be the cause for the issues I'm having?

 

 

Also specific to using the ufsession call, I tried this:

 

ufSes.Wave.CreateLinkedCurve(crv.Tag, my_xform.Tag, wrkPrt.Bodies.ToArray()(0).Tag, False, lnkdCrvTag)

which produced the same problem as using the WaveLinkBuilder. However I was unable to get it to work providing it an XForm created by the method mark_benson mentioned. It errored out citing "The second parameter passed in was invalid", meaning the XForm was invalid. (I created it as shown below) Any insight on this? (dspCmp is the Display Component)

 

 

Dim my_xform As Xform = nxSes.Parts.Work.Xforms.CreateXform(dspCmp, targetComponent, SmartObject.UpdateOption.WithinModeling)

 

 

 

 

 

 

 

Re: WAVE Linked Curves in Incorrect Locations

I've now gone through and both removed all usage of the Block Styler as well as rewriting it to be run as a .vb file (instead of a compiled .dll). Still no progress.

 

Will try writing a new program which only wavelinks curves from one component to another allowing the user to select said component to see if that's the issue.

Re: WAVE Linked Curves in Incorrect Locations

For the full definition of the xform I used:

 Dim comp_assy As ComponentAssembly = thesession.Parts.Work.ComponentAssembly
                    Dim root_comp As Component = comp_assy.RootComponent


                    Dim comp_tag As Tag = ufs.Assem.AskPartOccurrence(curve_objs(index).Tag)

                    Dim this_comp As Component

                    this_comp = nxobjectmanager.Get(comp_tag)



                    Dim my_xform As Xform = thesession.Parts.Work.Xforms.CreateXform(root_comp, this_comp, SmartObject.UpdateOption.WithinModeling)

This assumes you have added the component you are wavelinking from into your work part.

 

Re: WAVE Linked Curves in Incorrect Locations

ufSes.Wave.CreateLinkedCurve(crv.Tag, my_xform.Tag, wrkPrt.Bodies.ToArray()(0).Tag, False, lnkdCrvTag)

 

Having looked at this in more detail....

In your code I believe the third input is invalid.  This should be the tag of the part you want the object copied to.

Re: WAVE Linked Curves in Incorrect Locations

[ Edited ]

@mark_benson I tried that with both the tag of the target part as well as a body contained within the target part, both worked similarly, the error I had been getting was having an incorrect XForm. [Edit: I've also since moved away from using the ufSession calls and trying to use the WaveLinkBuilder.]

 

Here's a stripped down version of the program I've been trying to get working:

 

Option Strict Off
Imports System
Imports System.Collections.Generic
Imports NXOpen
Imports NXOpen.UF
Imports NXOpen.Assemblies
Imports NXOpen.Features

Module WaveLinkTest

    Dim nxSes As Session = Session.GetSession()
    Dim wrkPrt As Part = nxSes.Parts.Work

    Sub Main()
        Dim engravingComponent As Component = Nothing
        If SelectComponent("Select Engraving Component", engravingComponent) = Selection.Response.Cancel Then
            Return
        End If
        Dim crvs() As Curve = engravingComponent.Prototype.OwningPart.Curves.ToArray()
        Dim wavelink As CompositeCurve = WavelinkCurves(crvs)
        wavelink.SetName("Wavelinked Curves")

    End Sub

    Private Function WavelinkCurves(ByVal curves() As Curve) As CompositeCurve
        Dim wavLnkBldr As WaveLinkBuilder
        wavLnkBldr = wrkPrt.BaseFeatures.CreateWaveLinkBuilder(Nothing)
        wavLnkBldr.Type = WaveLinkBuilder.Types.CurveLink
        Dim crvBldr As CompositeCurveBuilder
        crvBldr = wavLnkBldr.CompositeCurveBuilder
        With crvBldr
            .AllowSelfIntersection = True
            .Section.DistanceTolerance = 0.0001
            .Section.ChainingTolerance = 0.000095
            .Associative = True
            .ParentPart = CompositeCurveBuilder.PartType.OtherPart
            .MakePositionIndependent = False
            .FixAtCurrentTimestamp = False
            .HideOriginal = False
            .InheritDisplayProperties = True
            .JoinOption = CompositeCurveBuilder.JoinMethod.No
            .Tolerance = 0.0001
        End With

        Dim section1 As Section
        section1 = crvBldr.Section
        section1.SetAllowedEntityTypes(Section.AllowTypes.CurvesAndPoints)
        section1.AllowSelfIntersection(True)

        For Each tmpCrv As Curve In curves
            Dim curveDumbRule1 As CurveDumbRule
            curveDumbRule1 = wrkPrt.ScRuleFactory.CreateRuleBaseCurveDumb({tmpCrv})
            Dim rules1() As SelectionIntentRule = {curveDumbRule1}

            Dim nullNXObject As NXObject = Nothing
            Dim helpPoint1 As Point3d = New Point3d(0.0, 0.0, 0.0)
            section1.AddToSection(rules1, tmpCrv, nullNXObject, nullNXObject, helpPoint1, Section.Mode.Create, False)
        Next

        WavelinkCurves = wavLnkBldr.Commit()
        wavLnkBldr.Destroy()
    End Function
End Module

 (To run the program make the Target Part your workpart and select the part with the curves via the UI.)

 

The problem as I understand it is that the Display Part's Absolute Coordinate System is not the same as the Target Part's. Because of this the wavelinked curves are put in the Target Part on it's Absolute CSys at what would be the location if the Absolute CSys of it and the Display Part were the same. (This means that if the CSys of the Target Part is 2.5" offset in the Z direction, the wavelinked curves will be 2.5" offset in the Z direction from their original locations.)

 

I've attached a .zip folder with 3 .prt's in it to demonstrate my problem:

Parent.prt which is the display part and contains the other two parts

textPart.prt which contains the curves which I want to wavelink

targetPart.prt which is where I want the curves to be wavelinked to (it also has a block in it and has been offset 2.5" in the Z direction)

 

What I'm trying to do is wavelink from TextPart to TargetPart. However TargetPart has other elements in it which need to be at a specific location in the DisplayPart (in this case the block), because of this TargetPart has been moved within DisplayPart so that their Absolute CSys do not match up. Whenever a wavelink program is run to do this the curves appear with the same 2.5" offset, however if you wavelink it manually then it's in the correct position.

 

I've tested this accross multiple computers and am starting to think that this may be a bug in NxOpen as opposed to me not understanding the process. If anyone wants to test this to make sure it's not just me or to try your own solutions, have at it.

Re: WAVE Linked Curves in Incorrect Locations

tVanHoeven,

 

I've had a look at this a little.

I think I'm starting to understand the problem.

I've noticed with the code I've been using with the xform and the UF function, that it works in the following scenario:

However fails in this scenario:

Giving the same error on the xform that you mentioned.

 

Our workflow tends to use Scenario 1 so I've not come across this problem before.

If I get more time I'll look into how my definition of the xform is working with the second scenario.  My only concern is picking out a consistent xform approach that works with complex assy structures.