Quantcast
Channel: Manufacturing DevBlog
Viewing all 519 articles
Browse latest View live

Configure filters for Vault API SelectEntity dialog

$
0
0

By Wayne Brill

You can specify a filter for the Select Entity dialog by using the ConfigureFilters() method on the SelectEntitySettings class. This method accepts a collection of EntityFilters which describe the behavior of each filter you want to supply to the dialog. Although the SDK doesn’t include an example of calling this method, it does provide a sample on how to create EntityFilters in the VaultBrowserSample app. (The Form1() constructor creates several entity filters).

After creating filters as in the sample pass the collection of filters to the SelectEntitySettings via the ConfigureFilters() method. You can see this done in the code example below.

Here is the SelectEntity dialog with the filters:

image

 

PublicSub select_a_File()

    Dim oFolder As ACW.Folder =
        m_conn.WebServiceManager.DocumentService.GetFolderByPath("$/Inventor_Files_WB/")

    Dim myInventorFileFolder AsNew Framework.Vault.Currency.Entities.Folder(m_conn, oFolder)

    Dim filters() As Forms.Settings.SelectEntitySettings.EntityRegularExpressionFilter = { _
        New Forms.Settings.SelectEntitySettings.EntityRegularExpressionFilter _
           ("Project Files (*.ipj)", ".+ipj", Vault.Currency.Entities.EntityClassIds.Files), _
        New Forms.Settings.SelectEntitySettings.EntityRegularExpressionFilter _
                ("Part Files (*.ipt)", ".+ipt", Vault.Currency.Entities.EntityClassIds.Files)
    }

    Dim initialFilter AsNew Forms.Settings.SelectEntitySettings.EntityRegularExpressionFilter _
                    ("Part Files (*.ipt)", ".+ipt", Vault.Currency.Entities.EntityClassIds.Files)

    Dim EntSettings As Framework.Vault.Forms.Settings.SelectEntitySettings =
                                      New Framework.Vault.Forms.Settings.SelectEntitySettings()

    With EntSettings
        .ActionableEntityClassIds.Add("FILE")
        .DialogCaption = "Select part"
        .MultipleSelect = False
        .ConfigureActionButtons("Select File", Nothing, Nothing, Nothing)
        .InitialBrowseLocation = myInventorFileFolder
        .ConfigureFilters("Project Files (*.ipj)", filters, initialFilter)
    EndWith

    Dim selEntsResults As Framework.Vault.Forms.Results.SelectEntityResults =
                        Framework.Vault.Forms.Library.SelectEntity(m_conn, EntSettings)
EndSub

Add-In security in Inventor 2017

$
0
0

By Adam Nagy

Couple of changes in Inventor 2017:

1) Digitally signed add-in

Inventor 2017 provides a new way of making an add-in load without the security dialog popping up: the add-in dll needs to be digitally signed with a certificate ...

SignedAddIn

... and the publisher of the certificate needs to be in the "Trusted Publishers" list:

TrustedPublisher 

This is something that could be done by your app's installer - e.g. the installer provided for App Store plugins will do it as well if your add-in is digitally signed.

2) AddInLoadRules in Inventor 2017

"AddInLoadRules.xml" files were introduced in Inventor 2016 and are used to track which add-ins should be allowed to load: 
https://knowledge.autodesk.com/support/inventor-products/troubleshooting/caas/CloudHelp/cloudhelp/2016/ENU/Inventor-Install/files/GUID-84B221D3-979B-420D-B955-9DCBDC0C5619-htm.html

Inventor 2017 is still using AddInLoadRules files with some changes compared to Inventor 2016. In Inventor 2017 we have the following files:

  • Administrator settings are stored in an xml file "C:\Program Files\Autodesk\Inventor 2017\Preferences\AddInLoadRules.xml"
  • User override settings are now stored in a binary file "%APPDATA%\Autodesk\Inventor 2017\Addins\AddInLoadRules"
    • If the user hasn’t saved any overrides, that binary file won’t exist yet
    • Additionally, since in prior releases the user override settings were in an xml file, we still honour those settings if that file is present - but only if the binary file is not present
    • Once user makes a change and save their settings, the new binary file is created

 

Forge DevCon Early Bird tickets ending this Firday! :)

$
0
0

By Adam Nagy

You might have heard by now of the biggest ever Autodesk Developer Conference coming this June, Forge DevCon

ForgeDevCon

The Early Bird tickets are running out this Friday, so you'll have to hurry up if you want to use them! :)

At the conference you can learn everything there is to know about our Forge Platform and how you can build on top of it.

Brian will be there to talk about Fusion API, and I will be there too explaining how you will be able to take advantage of our translation services to get data out of pretty much any design file you have.

There will be many tracks with great topics: http://forge.autodesk.com/tracks-and-speakers/ 

The same week we'll also have our 2nd 3d Web Festhttp://www.3dwebfest.com

3dWebFest

Then the following week we'll also hold a Cloud Accelerator, a program that we have run many times by now all around the world with great success. Here we work side-by-side with 3rd party developers to jump start their development on our cloud technologies.

It's looking to be a great couple of weeks that nobody should miss :) 

Rename the "User Commands" panel

$
0
0

By Adam Nagy

When adding VBA macro functions to the Ribbon through the "Customize User Commands..." button then they will appear in the "User Commands" panel.

UserCommands

RibbonPanel names cannot be changed, but maybe the panels could be replaced by other ones.

Instead of doing that though, I think the easiest might be just to create your own panel and add the macros to that. 

In this case I only have these two macros in my "Module1" and when I run "CreateMyPanel" then it will create a new panel called "MyPanel" and add a reference in it to the "MyMessage" macro.

Module1

Sub MyMessage()
  MsgBox "My message"
End Sub

Sub CreateMyPanel()
  Dim rs As Ribbons
  Set rs = ThisApplication.UserInterfaceManager.Ribbons
  
  Dim cds As ControlDefinitions
  Set cds = ThisApplication.CommandManager.ControlDefinitions
  
  Dim cd As MacroControlDefinition
  Set cd = cds.AddMacroControlDefinition("Module1.MyMessage")
  Dim r As Ribbon
  Set r = rs("Part")
  Dim t As RibbonTab
  Set t = r.RibbonTabs("id_TabTools")
  Dim p As RibbonPanel
  Set p = t.RibbonPanels.Add("MyPanel", "MyName.MyPanel", "MyName.MyPanel")
  Call p.CommandControls.AddMacro(cd)
End Sub

MyPanel

One thing to bear in mind is that programmatically added UI elements are not persisted. So you would have to run your command that adds the extra ribbon panel each time Inventor starts. The best way to do that would be to create an addin for that.  

 

Fusion API: Change Appearance of Body

$
0
0

By Xiaodong Liang

Various objects in Fusion 360 can be applied with material and appearance. Appearance is how the object looks like. While Material is the physical property of an object. It has a default appearance. e.g. in default an object with “Leather, weathered” would look like this.

clip_image001

However we can override its appearance with other type.

clip_image002

By this mean, the appearance of a material is not changed. Only the appearance of body is changed.

The corresponding APIs are:

  • BRepBody.material which is a Material object.

image

  • BrepBody.appearance which is an Appearance object.

image

So, if we test with the following JavaScript code before overriding the appearance, it will tell the material is “Leather, weathered” and material’s appearance and body’s appearance are both “Leather, weathered”. While after overriding, material is “Leather, weathered” and material’s appearance are not changed, but the body’s appearance is “Glass - Heavy Color (Blue)”

function run(context) {

    "use strict";
   
    if (adsk.debug === true) {
        /*jslint debug: true*/
        debugger;
        /*jslint debug: false*/
    }

    var ui;
    try {
        var app = adsk.core.Application.get();
        ui = app.userInterface;

        var product = app.activeProduct;
        var design = adsk.fusion.Design(product);
       
        //get the first body of the root component
        var rootComp = design.rootComponent;
        var body = rootComp.bRepBodies.item(0);
       
        //body material
        var bodyM = body.material;
        ui.messageBox('body material is: ' + bodyM.name);       
        //appearance with the material
        var MaterialA =bodyM.appearance;
        ui.messageBox('material appearance is: ' + MaterialA.name);
       
        //body appearance
        var BodyA = body.appearance;
        ui.messageBox('body appearance is: ' + BodyA.name);
    }
    catch (e) {
        if (ui) {
            ui.messageBox('Failed : ' + (e.description ? e.description : e));
        }
    }    

    adsk.terminate();
}

To change the material /appearance, you need to firstly get the new material/appearance from the libraries, and set them to object.material or object.appearance.

image

image

 

function run(context) {

    "use strict";
   
    if (adsk.debug === true) {
        /*jslint debug: true*/
        debugger;
        /*jslint debug: false*/
    }

    var ui;
    try {
        var app = adsk.core.Application.get();
        ui = app.userInterface;

        var product = app.activeProduct;
        var design = adsk.fusion.Design(product);
       
        //get the first body of the root component
        var rootComp = design.rootComponent;
        var body = rootComp.bRepBodies.item(0);
       
        //body material
        var bodyM = body.material;
        ui.messageBox('body material is: ' + bodyM.name);       
        //appearance with the material
        var MaterialA =bodyM.appearance;
        ui.messageBox('material appearance is: ' + MaterialA.name);
       
        //body appearance
        var BodyA = body.appearance;
        ui.messageBox('body appearance is: ' + BodyA.name);        
       
        //get material lib
        var mLibs = app.materialLibraries;               
        var mLib = mLibs.itemByName("Fusion 360 Material Library");        
        //get one material from this lib
        var mOne = mLib.materials.itemByName("ABS Plastic");
        //change body material
        body.material = mOne;
        app.activeViewport.refresh();
        ui.messageBox('take a look at the screen after material is changed: ');       
       
        //get appearance lib
        var appearanceLib1 = mLibs.itemByName("Fusion 360 Appearance Library");           
         //get one material from this lib
        var aOne = appearanceLib1.appearances.itemByName("Fabric (Green)");
        //change body appearance
        body.appearance = aOne;
        app.activeViewport.refresh(); 
        ui.messageBox('take a look at the screen after appearance is changed: ');       
      
    }
    catch (e) {
        if (ui) {
            ui.messageBox('Failed : ' + (e.description ? e.description : e));
        }
    }   
  

    adsk.terminate();
}

Inventor 2017

$
0
0

By Adam Nagy

In case you missed the news, Inventor 2017 has been available now for a couple of weeks.
There are articles covering the new features and even found a session about it on Lynda.com :)

There is also a webinar coming next week if you are interested:

Inventor2017

I as well already mentioned one of the changes in the new release: Add-In security in Inventor 2017

Just a quick view of the amount of API changes compared to previous releases:

Inventor2017API

You can find a complete list of what changed in the "What's New in Inventor 2017" section of the Inventor API Help File at "C:\Users\Public\Documents\Autodesk\Inventor 2017\Local Help\admapi_21_0.chm"

 

Modify DimensionText value of GeneralDimension

$
0
0

By Adam Nagy

If you created a DrawingSketch and placed some geometry there which you dimensioned (constrained), then you can drive the value of those.

In the UI if you wanted to change the dimension then you would either go into the sketch and double-click the dimension or modify it from the Parameters dialog. In both cases you are modifying the parameter that drives the dimension constraint to achieve what you need.  

SketchDimension

You would have to do exactly the same through the API as well. If you want to get to them for some reason through Sheet.DrawingDimensions.GeneralDimensions, that is possible too. From that collection you would get back e.g. a LinearGeneralDimension. Its DimensionText property can only modify what is shown in the UI for the dimension not the actual size of it:

SheetDimension

You can use the RetrievedFrom property to get to the Sketch dimension constraint, which will provide you the Parameter you need to modify.

Sub ModifyDimensions()
  Dim oDoc As DrawingDocument
  Set oDoc = ThisApplication.ActiveDocument
  Dim oSheet As Sheet
  Set oSheet = oDoc.ActiveSheet
  Dim oTO As TransientObjects
  Set oTO = ThisApplication.TransientObjects
  Dim oSketches As ObjectCollection
  Set oSketches = oTO.CreateObjectCollection

  Dim oDrawingDim As GeneralDimension
  For Each oDrawingDim In oSheet.DrawingDimensions.GeneralDimensions
    Dim dimGeneralDimText As DimensionText
    Set dimGeneralDimText = oDrawingDim.text
    
    Dim p As Parameter
    Set p = oDrawingDim.RetrievedFrom.Parameter
    p.Value = p.Value + 1 ' adding 1 cm to it' Note the sketch that will need an update
    Call oSketches.Add(oDrawingDim.RetrievedFrom.Parent)
  Next' Update the sketches
  Dim oSketch As DrawingSketch
  For Each oSketch In oSketches
    Call oSketch.Edit
    Call oSketch.Solve
    Call oSketch.ExitEdit
  Next
End Sub

Iterating through the DrawingSketch.DimensionConstraints collection would be an even simpler solution.  

Thumbnails when saving documents in hidden mode - change in Inventor 2017

$
0
0

By Wayne Brill

Versions of Inventor before the 2017 release do not generate a thumbnail when a document is saved in hidden mode. The thumbnails may not be correct in this situation. For example if a part is opened in hidden mode and a hole feature is added with the API in Inventor 2016 and saved, the thumbnail will not show the new hole.

Inventor 2017 has new functionality so the thumbnail is generated when the document is saved in hidden mode and the geometry of the thumbnail is correct. However the background may not be right. Currently there is a limitation where a picture background will not be used. A workaround is to open the file in visible mode and save it. (This limitation of the new implementation in Inventor 2017 has been reported to Engineering)

If the background is non-pictorial Inventor 2017 will use the application setting for the color scheme for the hidden files thumbnail background. If you want the background of hidden files to be a specific color scheme (non-picture) this can be achieved by modifying the Inventor 2017 Application settings. (Color Scheme)

 

Note: Document settings where never used to save thumbnails. (Both the background color scheme and background picture only exists in application setting). The reason why it may seem like there’s document setting for background in previous versions is that the thumbnail never re-generated in hidden files, so the background was always the same.


Insert copies of Content Center parts

$
0
0

By Adam Nagy

You might need to insert lots of instances of the same Content Center part in an assembly - e.g. placing rivets in similar holes on the same part. You could write some code that would help replicate an instance, so that you would only need to insert a single component manually then select the inserted component and all the holes where you would need the same component and the code would insert them and add the constraints.

This sample is just to show the idea and is far from a robust solution which would work in all scenarios. In this case we assume that the rivet has been placed with a single insert constraint and the selected holes are the same size as the original one.

So we already have a rivet placed in the assembly and now we select it and the other holes where we want to place them:

Rivets1

Then we run this VBA code:

Sub InsertSameInstances()
  Dim doc As AssemblyDocument
  Set doc = ThisApplication.ActiveDocument
  Dim acd As AssemblyComponentDefinition
  Set acd = doc.ComponentDefinition' Instance to copy
  Dim occ As ComponentOccurrence
  Set occ = doc.SelectSet(1)' Store selected faces
  Dim fs As ObjectCollection
  Set fs = ThisApplication.TransientObjects.CreateObjectCollection
  Dim i As Integer
  For i = 2 To doc.SelectSet.Count
    Call fs.Add(doc.SelectSet(i))
  Next' Faces of holes that the copies should be placed to
  Dim h As Face
  For Each h In fs' Insert same component
    Dim tg As TransientGeometry
    Set tg = ThisApplication.TransientGeometry
    Dim occNew As ComponentOccurrence
    Set occNew = acd.Occurrences.AddByComponentDefinition( _
      occ.Definition, tg.CreateMatrix())' Check original component's constraints
    Dim c As AssemblyConstraint
    For Each c In occ.Constraints
      If TypeOf c Is InsertConstraint Then
        Dim ic As InsertConstraint
        Set ic = c' Get native edge
        Dim e As Edge
        Set e = c.EntityOne.NativeObject' Get its equivalent in the new occurrence
        Dim ep As EdgeProxy
        Call occNew.CreateGeometryProxy(e, ep)' Get hole's edge
        Dim eh As Edge
        Set eh = h.Edges(1)
        Call acd.Constraints.AddInsertConstraint( _
          ep, eh, ic.AxesOpposed, ic.Distance.value)
      End If
    Next
  Next
End Sub

And get this:

Rivets2

I think based on this someone could create a nice Inventor App Store plugin - hint, hint ;)

Rotate sketch entities

$
0
0

By Adam Nagy

We have a function on the PlanarSketch object called RotateSketchObjects which takes a collection of SketchEntity's and rotates them around a given point. It seems that if I also pass in all the entities including the sketch points that the sketch curves depend on then it does not work, but if I omit the points and only pass in the sketch curves, that works fine: 

Sub RotateSketchEntities()
  Const PI = 3.14159265358979' Make sure that the Sketch is active in the UI' before running the code
  Dim sk As PlanarSketch
  Set sk = ThisApplication.ActiveEditObject
  Dim tro As TransientObjects
  Set tro = ThisApplication.TransientObjects
  Dim oc As ObjectCollection
  Set oc = tro.CreateObjectCollection
  Dim pt As SketchEntity
  For Each pt In sk.SketchEntities' Omit points
    If Not TypeOf pt Is SketchPoint Then
      Call oc.Add(pt)
    End If
  Next
  Dim trg As TransientGeometry
  Set trg = ThisApplication.TransientGeometry' Rotate them 90 degrees around origin point
  Call sk.RotateSketchObjects( _
    oc, trg.CreatePoint2d(), PI / 2#)
End Sub

Rotatesketch

 

Inventor 2017 - Removed Classes and Functions

$
0
0

By Wayne Brill (Information provided by Brian Ekins)

Compared to Inventor 2016 there are actually six removed objects and 45 removed functions.  (The data in the slide one this post was generated long before the release). The complete list is below.  The reason for so many removed functions is that some features implemented the “Definition” way of encapsulating the input used to create and edit those features. The “removed” functions weren’t actually removed but have been hidden and can continue to be used, although they’re not officially supported and developers should begin using the new way of creating and editing those features.

6 Removed Objects:

   MaterialsEnumerator

   PresentationExplodedView

   PresentationExplodedViews

   Trail

   TrailSegment

   TrailsEnumerator

45 Removed Functions:

   CircularPatternFeature.Angle

   CircularPatternFeature.AxisEntity

  CircularPatternFeature.ComputeType

   CircularPatternFeature.Count

   CircularPatternFeature.FitWithinAngle

   CircularPatternFeature.MidPlanePattern

   CircularPatternFeature.NaturalAxisDirection

   CircularPatternFeature.NewBodyOperation

   CircularPatternFeature.ParentFeatures

   CircularPatternFeature.PatternOfBody

   CircularPatternFeatures.Add

   ClientGraphicsCollection.AddNonTransacting

   CosmeticWeld.Edges

   DesignViewRepresentation.ModelAnnotationScale

   MirrorFeature.ComputeType

   MirrorFeature.MirrorOfBody

   MirrorFeature.MirrorPlaneEntity

   MirrorFeature.NewBodyOperation

   MirrorFeature.ParentFeatures

   MirrorFeatures.Add

   PresentationDocument.ActiveExplodedView

   PresentationDocument.PresentationExplodedViews

   RectangularPatternFeature.ComputeType

   RectangularPatternFeature.NaturalXDirection

   RectangularPatternFeature.NaturalYDirection

   RectangularPatternFeature.NewBodyOperation

   RectangularPatternFeature.OrientationMethod

   RectangularPatternFeature.ParentFeatures

   RectangularPatternFeature.PatternOfBody

   RectangularPatternFeature.XCount

   RectangularPatternFeature.XDirectionEntity

   RectangularPatternFeature.XDirectionMidPlanePattern

   RectangularPatternFeature.XDirectionSpacingType

   RectangularPatternFeature.XDirectionStartPoint

   RectangularPatternFeature.XSpacing

   RectangularPatternFeature.YCount

   RectangularPatternFeature.YDirectionEntity

   RectangularPatternFeature.YDirectionMidPlanePattern

   RectangularPatternFeature.YDirectionSpacingType

   RectangularPatternFeature.YDirectionStartPoint

   RectangularPatternFeature.YSpacing

   RectangularPatternFeatures.Add

   RuledSurfaceDefinition.Edges

   RuledSurfaceDefinition.GetExtendDirectionOnEdge

   RuledSurfaceDefinition.SetExtendDirectionOnEdge

Control Rendering Options for Inventor Studio with an Inventor Attribute

$
0
0

By Wayne Brill

There is not any Inventor API for Inventor Studio. A work around to control a setting for rendering as shown in this screenshot is to change the value of an Inventor attribute named "com.autodesk.archon.rendering that is stored in the document".

image 

 

Here is a VBA example that changes the “Render by iteration” setting.

 

Sub InventorStudioRenderOptions_test()
    Dim oDoc As Document
    Set oDoc = ThisApplication.ActiveDocument
   
    If oDoc.DocumentType <> kPartDocumentObject And _
             oDoc.DocumentType <> kAssemblyDocumentObject Then
        MsgBox "Please open a part or assembly document!"
        Exit Sub
    End If
   
    Dim oCompDef As ComponentDefinition
    Set oCompDef = oDoc.ComponentDefinition
   
    Dim oAttSet As AttributeSet
    
    If oCompDef.AttributeSets.NameIsUsed("com.autodesk.archon.rendering") Then
        Set oAttSet = oCompDef.AttributeSets("com.autodesk.archon.rendering")
    Else
        Set oAttSet = oCompDef.AttributeSets.Add("com.autodesk.archon.rendering")
    End If
   
    Dim oAtt As Inventor.Attribute
   
    If oAttSet.NameIsUsed("Options") Then
        Set oAtt = oAttSet.Item("Options")

        'Get the value of the attribute
        Dim strAttValue As String
        strAttValue = oAtt.Value
       
        Dim XDoc As Object
        Set XDoc = CreateObject("MSXML2.DOMDocument")
       
        XDoc.async = False: XDoc.validateOnParse = False
        ' load the value of the Inventor attribute into the XML doc
        XDoc.loadXML strAttValue
 
        Dim optionsXMLNodeSel As Object
        Set optionsXMLNodeSel = XDoc.selectNodes("Options")
      
        Dim optionsXMLElement As IXMLDOMElement
        Set optionsXMLElement = optionsXMLNodeSel(0)
            
        Dim strAtt As String
        strAtt = optionsXMLElement.getAttribute("RayTracingDuration")
       
       ' Change the option (XML attribute)
        Call optionsXMLElement.setAttribute("RayTracingDuration", 45)
        
        'Update the Inventor attribute
        oAtt.Value = XDoc.XML

    Else
        Dim sWidth As String, sHeight As String
        sWidth = oDoc.Views(1).Width
        sHeight = oDoc.Views(1).Height

        ' Set the Iteration value
        Dim sIteration As String
        sIteration = "80.0"

        Dim sValue As String
        sValue = "<?xml version="& """"& "1.0"& """"& " encoding="& """"& "UTF-16"& """"& "?>"& vbCrLf
        sValue = sValue & "<Options Version="& """"& "2"& """"& " RenderW="& """"& sWidth & """" _
                        & " RenderH="& """"& sHeight & """"& " RayTracingDuration="& """"& sIteration & """"& "/>"

        Set oAtt = oAttSet.Add("Options", kStringType, sValue)
    End If
End Sub

Pre-DevCon Workshops

$
0
0

By Adam Nagy

In case you did not spot this on the Forge DevCon site, the day before the conference we are also organizing workshops that you're welcome to attend - including a Fusion 360 API workshop with Brian and a few of us :)

DevConWorkshops

See you there! :)

Is SketchPoint part of a curve?

$
0
0

By Adam Nagy

If you want to check if a SketchPoint is part of a curve (e.g. the control points of a SketchControlPointSpline) vs just a point standing on it's own, then you can do that using the SketchPoint's AttachedEntities property.

As always, the easiest way to find out about this is if you investigate the object in the VBA Watches window:
http://adndevblog.typepad.com/manufacturing/2013/10/discover-object-model.html

If you select the control point in the UI:

SketchPointUI

.. then you'll get this in the Watches window:

SketchPoint

 

Update to Vault 2017 SDK help LegacyFileTransfer.cs example

$
0
0

By Wayne Brill

The topic “ How To Acquire Files” in the the Vault 2017 SDK has a section titled: “File Transfer - Doing it the Hard Way”. In that section there are a couple of links to C# and VB examples. The DownloadFile function in these examples will not work with Vault 2017 due to the change to the DownloadFilePart method. It has changed in 2017 and doesn't return a byte array anymore, but a stream instead.

Here is an update to the DownloadFile function that works with the 2017 API.

privatestaticvoid DownloadFile(vltutil.WebServiceManager mgr, outbyte[] fileContents,
                                                vltobj.ByteArray downloadTicket, bool allowSync)
{
    mgr.FilestoreService.CompressionHeaderValue = new vltobj.CompressionHeader();
    mgr.FilestoreService.CompressionHeaderValue.Supported = vltobj.Compression.None;
    mgr.FilestoreService.FileTransferHeaderValue = new vltobj.FileTransferHeader();
    mgr.FilestoreService.FileTransferHeaderValue = null;

    using (System.IO.MemoryStream stream = new System.IO.MemoryStream())
    {
        long bytesRead = 0;
        while (mgr.FilestoreService.FileTransferHeaderValue == null ||
                                    !mgr.FilestoreService.FileTransferHeaderValue.IsComplete)
        {
            using (Stream filePart = mgr.FilestoreService.DownloadFilePart(downloadTicket.Bytes,
                                            bytesRead, bytesRead + MAX_FILE_PART_SIZE - 1, allowSync))
            {
                int chunkSize = (mgr.FilestoreService.FileTransferHeaderValue != null) ?
                                    mgr.FilestoreService.FileTransferHeaderValue.UncompressedSize : 0;
                if (chunkSize > 0)
                {
                    filePart.CopyTo(stream);
                    bytesRead += chunkSize;
                }
            }
        }

        fileContents = newbyte[bytesRead];
        if (bytesRead > 0)
        {
            stream.Seek(0, System.IO.SeekOrigin.Begin);
            stream.Read(fileContents, 0, (int)bytesRead);
        }
    }
}

Demote OccurrencePattern

$
0
0

By Adam Nagy

There is a sample in the API Help about demoting an occurrence using the BrowserPane.Reorder function - search for "Demote occurrence API Sample"
However, it does not work in case of an OccurrencePattern, because that is not supported by the product either:

OccurrenceVsPattern
If you think this would be something useful to have in the product then please log it on the IdeaStation:
http://forums.autodesk.com/t5/inventor-ideas/idb-p/v1232/tab/most-recent

There is another way to demote a component however: use the "AssemblyDemoteCmd" control definition.
Just make sure that you are selecting the correct component - if you select Occurrences(1) that will only return an item inside the pattern and not the pattern object itself:

OccurrencePattern

Sub DemoteWithCommand()

Dim oDoc As AssemblyDocument
Set oDoc = ThisApplication.ActiveDocument

Dim oDef As AssemblyComponentDefinition
Set oDef = oDoc.ComponentDefinition

'Set a reference to the first occurrence
Dim oOcc As ComponentOccurrence
Set oOcc = oDef.Occurrences.Item(1)

Dim oItemToMove As Object
If oOcc.IsPatternElement Then
    Set oItemToMove = oOcc.PatternElement.Parent
Else
    Set oItemToMove = oOcc
End If

'Clear select set
oDoc.SelectSet.Clear'Add the occurrence to demote to the select set
oDoc.SelectSet.Select oItemToMove

ThisApplication.SilentOperation = True

Dim oCM As CommandManager
Set oCM = ThisApplication.CommandManager

' Prepopulate the file name of new component in' the 'Create Component' dialog
oCM.PostPrivateEvent kFileNameEvent, "C:\temp\test\demoted.iam"

Dim oControlDef As ControlDefinition
Set oControlDef = oCM.ControlDefinitions("AssemblyDemoteCmd")' Execute the demote command
oControlDef.Execute

ThisApplication.SilentOperation = False

End Sub

 

Access a specific Inventor.Application object

$
0
0

By Adam Nagy

When running multiple instances of Inventor (or AutoCAD, MicrosoftExcel, etc) then even though the ROT (Running Objects Table) lists all the running instances, they will all return the same Inventor.Application object that is returned by GetActiveObject as well - i.e. the first Inventor instance. See comments of this blog post: 
http://adndevblog.typepad.com/autocad/2013/12/accessing-com-applications-from-the-running-object-table.html

The ROT also returns the currently open documents (Inventor.Document object) and those have the correct COM reference. So from those you can find the various Inventor.Application objects.  Of course this only works for the Inventor instances which have documents open in them - and those documents need to be unique. E.g. if in Inventor instance #2 I open "mypart.ipt" then I also open the same file in Inventor instance #3 then that document will only have a single reference in the ROT and that will reference Inventor instance #2. I won't be able to access Inventor instance #3.

If you are trying to access the Inventor instance that you create through CreateProcess then one workaround is to create a copy of a template document with a unique name and open that in Inventor.

using System;
using System.Diagnostics;
using System.Runtime.InteropServices;
using System.Runtime.InteropServices.ComTypes;

namespace InventorConsoleAppCSharp
{
  classProgram
  {

    [DllImport("ole32.dll")]
    staticexternint CreateBindCtx(
        uint reserved,
        outIBindCtx ppbc);

    [DllImport("ole32.dll")]
    publicstaticexternvoid GetRunningObjectTable(
        int reserved,
        outIRunningObjectTable prot);

    // Requires Using System.Runtime.InteropServices.ComTypes
    // Get all running instance by querying ROT
    privatestaticobject GetInventorApplicationWithWindowHandle(IntPtr hwnd)
    {
      // get Running Object Table ...
      IRunningObjectTable Rot = null;
      GetRunningObjectTable(0, out Rot);
      if (Rot == null)
        returnnull;

      // get enumerator for ROT entries
      IEnumMoniker monikerEnumerator = null;
      Rot.EnumRunning(out monikerEnumerator);

      if (monikerEnumerator == null)
        returnnull;

      monikerEnumerator.Reset();

      IntPtr pNumFetched = newIntPtr();
      IMoniker[] monikers = newIMoniker[1];

      // go through all entries and identifies app instances
      while (monikerEnumerator.Next(1, monikers, pNumFetched) == 0)
      {
        IBindCtx bindCtx;
        CreateBindCtx(0, out bindCtx);
        if (bindCtx == null)
          continue;

        string displayName;
        monikers[0].GetDisplayName(bindCtx, null, out displayName);
        System.Console.WriteLine(displayName);

        object ComObject;
        Rot.GetObject(monikers[0], out ComObject);

        if (ComObject == null)
          continue;

        try
        {
          dynamic invDoc = ComObject;
          if (newIntPtr(invDoc.Parent.MainFrameHWND) == hwnd)
          {
            // The parent of the document is the Application
            return invDoc.Parent;
          }
        }
        catch { }
      }

      returnnull;
    }

    staticvoid Main(string[] args)
    {
      // Create document with unique name
      string fileName = "C:\\temp\\" + Guid.NewGuid().ToString() + ".ipt";
      System.IO.File.Copy(
        "C:\\temp\\Gusset2013.ipt",
        fileName);

      // Start Inventor
      Process process = Process.Start(
        @"C:\Program Files\Autodesk\Inventor 2016\Bin\Inventor.exe",
        "\"" + fileName + "\"");

      // Wait until Inventor is fully ready
      process.WaitForInputIdle();
      while (process.MainWindowTitle == "")
      {
        process.Refresh();
        System.Threading.Thread.Sleep(1000);
      }

      // Get all the Inventor.Application objects
      // registered in the ROT
      // ROT = Running Objects Table
      Inventor.Application app = null;
      for (; app == null; System.Threading.Thread.Sleep(1000))
      {
        // Find the Inventor.Application object with
        // the correct window handle
        app = GetInventorApplicationWithWindowHandle(process.MainWindowHandle)
          as Inventor.Application;
      }

      Console.WriteLine("Found Inventor.Application object with title:\n" + app.Caption);

      // Let's close file and delete it
      app.Documents.get_ItemByName(fileName).Close();
      System.IO.File.Delete(fileName);

      // Wait for user to finish
      Console.WriteLine("Press key to exit");
      Console.ReadKey();
    }
  }
}

 

Get Closest Point on DrawingCurve

$
0
0

By Xiaodong Liang  

A customer wanted to get the closest point on a drawing curve when the user clicks a location on the sheet. The workflow is simple: start mouse event, watch MouseEvent.OnMouseClick. In the event, calculate the closest point on the curve. 

2016-7-1 15-16-37

However, it looks API only provides GetClosestPoint method for Edge and Face. So we would need to calculate the closest point ourselves. There are many discussions on the algorism how to get a nearest point of 2D curve, I tested with the simplest one: disperse the parameters of a curve, then get the point, calculate the distance with the mouse point, find the shortest one. 

The below is the code of MouseEvent. The whole code project is attached. It is a standalone EXE. It assumes a drawing curve is selected, then click [start event], mouse click a location, the closest point will be displayed as a client graphics point. Click [stop event] to terminate the custom mouse event.

Download ClosesPoint

you can change to other more efficient algorism of getting close point.

 

 Private Sub oME_OnMouseClick(Button As MouseButtonEnum, ShiftKeys As ShiftStateEnum, ModelPosition As Point, ViewPosition As Point2d, View As View) Handles oME.OnMouseClick
        Dim oPickPtX = ModelPosition.X
        Dim oPickPtY = ModelPosition.Y


        Dim oCurve As DrawingCurve
        oCurve = oOneDrawingCurve.Parent
         
        Dim oEvaluator As Curve2dEvaluator
        oEvaluator = oCurve.Evaluator2D

        Dim oMinP, oMaxP
        oEvaluator.GetParamExtents(oMinP, oMaxP)

        Dim oMinDis = 100000000000.0 

        ' Get the curve length
        Dim dLen As Double
        Call oEvaluator.GetLengthAtParam(oMinP, oMaxP, dLen)

        Dim dInc As Double
        dInc = dLen / 100  'consider 100 points         

        Dim dLenInc As Double
        dLenInc = 0

        Dim dparams(0) As Double
        dparams(0) = oMinP

        Dim iCnt As Integer

        Dim oClosestPtX As Double = 0
        Dim oClosestPtY As Double = 0

        For iCnt = 0 To 100
            Dim dParam As Double
            Call oEvaluator.GetParamAtLength(oMinP,
                               dInc * iCnt,
                               dParam)
            ' a spline in planar sketch is 2d. its points are' 2d (x,y)
            Dim dPts(1) As Double
            dparams(0) = dParam

            Call oEvaluator.GetPointAtParam(dparams, dPts)

            Dim oEachDis = Math.Sqrt(Math.Pow((dPts(0) - oPickPtX), 2) + 
Math.Pow((dPts(1) - oPickPtY), 2))'smaller distance? If (oEachDis < oMinDis) Then oMinDis = oEachDis oClosestPtX = dPts(0) oClosestPtY = dPts(1) End If Next 'draw the point graphics Dim oCoordSet As Object = Nothing Dim oGraphicsNode As Object = Nothing Dim oDataSets As Object = Nothing'get datasets, dataset, graphics node getCG(oGraphicsNode, oCoordSet, oDataSets)'prepare the coordinates Dim oPointCoords(2) As Double oPointCoords(0) = oClosestPtX : oPointCoords(1) = oClosestPtY : oPointCoords(2) = 0'oPointCoords(0) = dPts(0) : oPointCoords(1) = dPts(1) : oPointCoords(2) = 0 Call oCoordSet.PutCoordinates(oPointCoords) 'add PointGraphics Dim oPointGraphics As PointGraphics oPointGraphics = oGraphicsNode.AddPointGraphics'set the related oPointGraphics.PointRenderStyle = PointRenderStyleEnum.kCrossPointStyle oPointGraphics.CoordinateSet = oCoordSet oPointGraphics.BurnThrough = True invApp.ActiveView.Update() End Sub

2016-7-1 15-28-37

Filter out faces not facing the user

$
0
0

By Adam Nagy

The API Help contains a sample that lets you prompt the user to select a Face. This is helped by the option of specifying the object types we allow:

oSelectEvents.AddSelectionFilter filter

If you need more granularity when deciding which faces should be selectable then you can just handle the OnPreSelect event of the SelectEvents object. There you can check e.g. if the Face is planar or not, and in which direction its Normal is pointing. If e.g. it's pointing away from the user then you could make it not selectable:

Module

Public Sub TestSelection()' Create a new clsSelect object.
    Dim oSelect As New clsSelect' Call the pick method of the clsSelect object and set' the filter to pick any face.
    Dim oFaces As ObjectsEnumerator
    Set oFaces = oSelect.Pick(kPartFaceFilter)' Check to make sure an object was selected.
    Dim oSelSet As SelectSet
    Set oSelSet = ThisApplication.ActiveDocument.SelectSet
    For Each oFace In oFaces
      oSelSet.Select oFace
    Next
End Sub

clsSelect

'*************************************************************' The declarations and functions below need to be copied into' a class module whose name is "clsSelect". The name can be' changed but you'll need to change the declaration in the' calling function "TestSelection" to use the new name.' Declare the event objects
Private WithEvents oInteractEvents As InteractionEvents
Private WithEvents oSelectEvents As SelectEvents' Declare a flag that's used to determine when selection stops.
Private bStillSelecting As Boolean

Public Function Pick(filter As SelectionFilterEnum) As ObjectsEnumerator
  ' Initialize flag.
  bStillSelecting = True' Create an InteractionEvents object.
  Set oInteractEvents = ThisApplication.CommandManager.CreateInteractionEvents' Ensure interaction is enabled.
  oInteractEvents.InteractionDisabled = False' Set a reference to the select events.
  Set oSelectEvents = oInteractEvents.SelectEvents
  oSelectEvents.WindowSelectEnabled = True' Set the filter using the value passed in.
  oSelectEvents.AddSelectionFilter filter' Start the InteractionEvents object.
  oInteractEvents.Start' Loop until a selection is made.
  Do While bStillSelecting
    ThisApplication.UserInterfaceManager.DoEvents
  Loop' Get the selected item. If more than one thing was selected,' just get the first item and ignore the rest.
  Dim oSelectedEnts As ObjectsEnumerator
  Set oSelectedEnts = oSelectEvents.SelectedEntities
  If oSelectedEnts.Count > 0 Then
    Set Pick = oSelectedEnts
  Else
    Set Pick = Nothing
  End If' Stop the InteractionEvents object.
  oInteractEvents.Stop' Clean up.
  Set oSelectEvents = Nothing
  Set oInteractEvents = Nothing
End Function

Private Sub oInteractEvents_OnTerminate()
  ' Set the flag to indicate we're done.
  bStillSelecting = False
End Sub

Private Sub oSelectEvents_OnPreSelect( _
PreSelectEntity As Object, DoHighlight As Boolean, _
MorePreSelectEntities As ObjectCollection, _
ByVal SelectionDevice As SelectionDeviceEnum, _
ByVal ModelPosition As Point, _
ByVal ViewPosition As Point2d, ByVal View As View)
   If Not TypeOf PreSelectEntity Is Face Then Exit Sub
   
   Dim oFace As Face
   Set oFace = PreSelectEntity
   
   If Not TypeOf oFace.Geometry Is Plane Then Exit Sub
   
   Dim oPlane As Plane
   Set oPlane = oFace.Geometry
   
   Dim oViewDir As Vector
   Set oViewDir = View.Camera.Eye.VectorTo(View.Camera.Target)
   
   If oFace.IsParamReversed Then
     oViewDir.ScaleBy -1
   End If
   
   ' The direction the user is looking into and the face's' normal the same then the dot product is positive, so' we won't highlight the face
   If oPlane.Normal.DotProduct(oViewDir.AsUnitVector()) > 0 Then' Without this all 6 faces of the box would be selected
     DoHighlight = False
   End If
End Sub

Private Sub oSelectEvents_OnSelect( _
ByVal JustSelectedEntities As ObjectsEnumerator, _
ByVal SelectionDevice As SelectionDeviceEnum, _
ByVal ModelPosition As Point, ByVal ViewPosition As Point2d, ByVal View As View)
  ' Set the flag to indicate we're done.
  bStillSelecting = False
End Sub

FaceSelection

Only the 3 user facing faces are selected.

Configure Options of SaveAs DWG of Part or Assembly

$
0
0

By Xiaodong Liang

Question:
When we export document to DWG, the options are provided with an *,ini file. It works well with the DrawingDocument. While when saving as part/assembly file to DWG, there are some other options.

But it looks *.ini file does not work with Part or Assembly. How can we configure them?

image

 

Solution:

Those additional options can be explicitly appended to Option array. The code below is a demo. 

Public Sub PublishDWG()
    ' Get the DWG translator Add-In.
    Dim DWGAddIn As TranslatorAddIn
    Set DWGAddIn = ThisApplication.ApplicationAddIns.ItemById("{C24E3AC2-122E-11D5-8E91-0010B541CD80}")

    'Set a reference to the active document (the document to be published).
    Dim oDocument As Document
    Set oDocument = ThisApplication.ActiveDocument
        
    Dim oContext As TranslationContext
    Set oContext = ThisApplication.TransientObjects.CreateTranslationContext
    oContext.Type = kFileBrowseIOMechanism

    ' Create a NameValueMap object
    Dim oOptions As NameValueMap
    Set oOptions = ThisApplication.TransientObjects.CreateNameValueMap

    ' Create a DataMedium object
    Dim oDataMedium As DataMedium
    Set oDataMedium = ThisApplication.TransientObjects.CreateDataMedium

    ' Check whether the translator has 'SaveCopyAs' options
    If DWGAddIn.HasSaveCopyAsOptions(oDocument, oContext, oOptions) Then
        
        If oDocument.DocumentType = kPartDocumentObject Or oDocument.DocumentType = kAssemblyDocumentObject Then
            oOptions.Value("Solid") = True
            oOptions.Value("Surface") = True
            oOptions.Value("Sketch") = True
            oOptions.Value("DwgVersion") = 31
        End If
        
        If oDocument.DocumentType = kDrawingDocumentObject Then
            Dim strIniFile As String
            strIniFile = "C:\tempDWGOut.ini"
            ' Create the name-value that specifies the ini file to use.
            oOptions.Value("Export_Acad_IniFile") = strIniFile
        End If
    End If

    'Set the destination file name
    oDataMedium.FileName = "c:\tempdwgout.dwg"

    'Publish document.
    Call DWGAddIn.SaveCopyAs(oDocument, oContext, oOptions, oDataMedium)
End Sub
Viewing all 519 articles
Browse latest View live