Post on 30-Mar-2023
All rights reserved. No parts of this work may be reproduced in any form or by any means - graphic, electronic, ormechanical, including photocopying, recording, taping, or information storage and retrieval systems - without thewritten permission of the publisher.
Products that are referred to in this document may be either trademarks and/or registered trademarks of therespective owners. The publisher and the author make no claim to these trademarks.
While every precaution has been taken in the preparation of this document, the publisher and the author assume noresponsibility for errors or omissions, or for damages resulting from the use of information contained in this documentor from the use of programs and source code that may accompany it. In no event shall the publisher and the author beliable for any loss of profit or any other commercial damage caused or alleged to have been caused directly orindirectly by this document.
Printed: maggio 2022 in San Giorgio su Legnano, Italy.
Autodesk Inventor Programming in C++ byOwen Ransen(C) 2021 Owen F Ransen
Publisher
Managing Editor
Technical Editor
Cover Designer
Ransen Software
Owen Ransen
O. F. Ransen
O. Ransen
Production
Owen F. Ransen
Team Coordinator
Owen Frederick Ransen
3Contents
(C) 2021 Owen F Ransen
Table of Contents
Foreword 0
Part I Autodesk Inventor Programmingin C++ 15
Part II 0) Installing the SDK 15
Part III 1) How to use this help file (READTHIS FIRST) 17
Part IV 2) Introduction 18
Part V 3) Connecting to Inventor from aWindows MFC app. 18
Part VI 4) Pointers to Inventor and usefulInventor API objects. 20
Part VII 5) Running Inventorprogramatically 22
Part VIII 6) Creating a part document and asketch 22
Part IX 7) Some tips for Autodesk InventorC++ programmers 25
Part X Right hand coordinate system 27
Part XI iLogic and VBA 27
................................................................................................................................... 271 iLogic editing
................................................................................................................................... 282 iLogic and suppression of parts in assemblies
................................................................................................................................... 293 Run an EXE from inside an iLogc rule
................................................................................................................................... 304 iLogic suppression of features in a part
................................................................................................................................... 305 iLogic and part parameters
................................................................................................................................... 316 iLogic to delete suppressed compoents
................................................................................................................................... 317 iLogic debugging statements, Trace
................................................................................................................................... 338 iLogic to change dimensions in sketches
................................................................................................................................... 339 iLogic to add parts to an assembly
................................................................................................................................... 3410 iLogic iProperties example
Autodesk Inventor Programming in C++ by Owen Ransen4
(C) 2021 Owen F Ransen
................................................................................................................................... 3511 Local or global VBA?
................................................................................................................................... 3612 Listing documents open in Inventor with VBA
................................................................................................................................... 3713 VBA document type
................................................................................................................................... 3814 Inventor VBA and Excel
................................................................................................................................... 3815 Update custom iproperty with VBA and iLogic
................................................................................................................................... 3916 Shared global variables in iLogic
................................................................................................................................... 3917 Declaring variables in iLogic
................................................................................................................................... 4018 iLogic dialog form modification
................................................................................................................................... 4019 iLogic, adding a new form
................................................................................................................................... 4120 When do iLogic rules run?
................................................................................................................................... 4321 Inventor from inside Access
................................................................................................................................... 4422 Custom iProperties in component with VBA
Part XII Programming Inventor in C++ 44
................................................................................................................................... 451 Get the name of a part
................................................................................................................................... 462 Zoom
................................................................................................................................... 463 GetWorkPlaneName GetOccurrenceName
................................................................................................................................... 474 Investigating Asset Libraries Progamatically
................................................................................................................................... 495 Bounding box of a part occurrence in an assembly
................................................................................................................................... 496 Parallel planes programatically
................................................................................................................................... 517 Change size of a hole
................................................................................................................................... 528 Materials API
................................................................................................................................... 579 Model and User parameters programatically
................................................................................................................................... 5910 FlipNormal failure
................................................................................................................................... 6011 Adaptive geometry
................................................................................................................................... 6112 Add a sketch to an assembly or part
................................................................................................................................... 6313 How to get the value of a user parameter
................................................................................................................................... 6514 Getting the value of a custom iProperty
................................................................................................................................... 6615 Add a part to an assembly
................................................................................................................................... 6816 Open an assembly part programatically
................................................................................................................................... 7017 Landscape and Portrait orientation getting and setting
................................................................................................................................... 7118 Adding a sheet to a drawing
................................................................................................................................... 7319 Compile/Link Errors and how to correct them
......................................................................................................................................................... 73_WIN32_WINNT error
......................................................................................................................................................... 74error MSB3075: The command regsvr32 /s /c...
......................................................................................................................................................... 74Error MK_E_UNAVAILABLE 0x800401e3
......................................................................................................................................................... 75Include file paths
......................................................................................................................................................... 76CLSIDFromProgID error resolution
......................................................................................................................................................... 77C2064: term does not evaluate to a function taking 0 arguments
......................................................................................................................................................... 77C2774 compile error
......................................................................................................................................................... 78Failed to register
......................................................................................................................................................... 78Four API methods warning when compiling for MFC
5Contents
(C) 2021 Owen F Ransen
................................................................................................................................... 7920 Open an Inventor part programatically
................................................................................................................................... 8021 PutFullFileName exception
................................................................................................................................... 8022 MessageBox vs MsgBox
................................................................................................................................... 8123 InternalName vs DisplayName
................................................................................................................................... 8124 Add a circle to a sketch function
................................................................................................................................... 8225 Standard WorkPlane getting
................................................................................................................................... 8326 Creating folders in the browser programatically
................................................................................................................................... 8427 Getting the names of browser folders
................................................................................................................................... 8528 How to set the BOM Reference property in a part occurrence
................................................................................................................................... 8529 Listing the contents of a model view BOM
................................................................................................................................... 8730 Static quantity in a BOM
................................................................................................................................... 8831 Documents referenced by a 2d view in an IDW
................................................................................................................................... 8932 Add a DrawingSketch to a DrawingDocument
................................................................................................................................... 9033 Adding lines text and circles to a DrawingSketch
................................................................................................................................... 9234 Constrain a sketch point to a coordinate
................................................................................................................................... 9535 Get a Document from a Definition
................................................................................................................................... 9636 CreateSafeStringArray and CreateSafeDoubleArray
................................................................................................................................... 9737 Listing 2d points in a sketch
................................................................................................................................... 9738 gkVarEmpty
................................................................................................................................... 9739 Add an iMate (based on a point) into an assembly
................................................................................................................................... 9940 Part Lists programatically
................................................................................................................................... 10141 Add an assembly into another assembly programatically
................................................................................................................................... 10242 Hide a sketch in a part
................................................................................................................................... 10343 Range BBox of a PartsList
................................................................................................................................... 10344 Add a unitless user parameter into an assembly
................................................................................................................................... 10445 Create an ObjectCollection of parts in an assembly
................................................................................................................................... 10646 Delete a feature in a part
................................................................................................................................... 10647 Loop over part occurences in an assembly
................................................................................................................................... 10848 Add a rectangle to a sketch
................................................................................................................................... 10949 Rectangular cut with extrusion
................................................................................................................................... 11150 WorkAxis constraints
................................................................................................................................... 11251 Getting hold of the standard workpoint called "Center Point"
................................................................................................................................... 11252 Add a WorkPoint into an assembly programatically
................................................................................................................................... 11353 Add a WorkPoint at the intersection of a line and a plane
................................................................................................................................... 11454 Add grounded WorkAxis in an assembly
................................................................................................................................... 11755 List iMates in an assembly
................................................................................................................................... 11856 Filename of referenced doc
................................................................................................................................... 11857 Referenced Document of a View
................................................................................................................................... 12058 put_Name, how to use it
Autodesk Inventor Programming in C++ by Owen Ransen6
(C) 2021 Owen F Ransen
................................................................................................................................... 12059 Retrievable Dimensions
................................................................................................................................... 12660 DrawingDimensions vs GeneralDimensions
................................................................................................................................... 12761 Negative Dimensions
................................................................................................................................... 12862 Show a dimension programatically
................................................................................................................................... 13163 Dimensions in a drawing sheet
................................................................................................................................... 13264 Plane object, getting its geometry
................................................................................................................................... 13365 Open a part from a view
................................................................................................................................... 13466 getType and ObjectTypeEnum
................................................................................................................................... 13767 Listing types of dimensions in a view
................................................................................................................................... 13868 Getting the version of Inventor programatically
................................................................................................................................... 13969 QueryInterface and Release Etc
................................................................................................................................... 14070 CComQIPtr is better than QueryInterface
................................................................................................................................... 14071 How to get iPart factory parent from child member
................................................................................................................................... 14172 Counting the number of documents open in Inventor
................................................................................................................................... 14373 CustomTables in Sheets and Drawings
................................................................................................................................... 14674 Positioning objects in a Sheet.
................................................................................................................................... 14675 New line within table cells
................................................................................................................................... 14776 CreateDoubleVariantArray
................................................................................................................................... 14877 Create a drawing file (IDW or DWG)
................................................................................................................................... 14978 How to add views to a drawing sheet (Inventor API)
................................................................................................................................... 15279 Names of views programatically
................................................................................................................................... 15380 Creating projected views from base views
................................................................................................................................... 15481 Drawing View Styles
................................................................................................................................... 15582 Close function for Parts and Assemblies
................................................................................................................................... 15583 GetInventorDocTypeDesc
................................................................................................................................... 15684 Getting the current document of Inventor
................................................................................................................................... 15885 HRESULT codes
................................................................................................................................... 16086 Add a mate constraint with two planes programatically
................................................................................................................................... 16287 GetGeometryProxy
................................................................................................................................... 16388 Proxies, why and what?
................................................................................................................................... 16689 ErrorManager, errors and warnings, ShowCOMError and ReturnAndShowCOMError
................................................................................................................................... 16890 Looping over views in sheets
................................................................................................................................... 16991 Listing and checking constraints
................................................................................................................................... 17092 Saving apparently disabled (SilentOperation)
................................................................................................................................... 17093 WorkAxes in Inventor programs
................................................................................................................................... 17294 Wrapping COM and C++
................................................................................................................................... 17395 Units when programming Inventor
................................................................................................................................... 17496 Exporting Paramenters
................................................................................................................................... 17497 Placing objects in space Vector and Matrix
7Contents
(C) 2021 Owen F Ransen
................................................................................................................................... 17698 ObjectCollections in the Inventor API (transient object collections)
................................................................................................................................... 17799 Creating a new Part Document
................................................................................................................................... 178100 How to extrude a sketch programatically
................................................................................................................................... 183101 Transient Geometry
................................................................................................................................... 185102 Changing the application visibility
................................................................................................................................... 185103 A matrix to rotate an object
................................................................................................................................... 187104 Proxies, WorkAxes, Vectors and Points
................................................................................................................................... 188105 WorkFeatures and iParts
................................................................................................................................... 190106 What are PatternElements?
................................................................................................................................... 191107 Listing the contents of Patterns
................................................................................................................................... 194108 Pattern counts
................................................................................................................................... 194109 What sort of WorkFeature is this?
................................................................................................................................... 195110 IDispatch
................................................................................................................................... 196111 AddByPlaneAndOffset example
................................................................................................................................... 197112 Interrogating rectangular patterns
................................................................................................................................... 198113 Name of part in a component occurrence
................................................................................................................................... 201114 Add an occurrence to an assembly does not work
................................................................................................................................... 201115 Listing constraints in an assembly programatically
................................................................................................................................... 203116 Listing members in an iPartFactory programatically
................................................................................................................................... 205117 PartComponentDefinition from an occurrence
................................................................................................................................... 206118 AddiPartMember
................................................................................................................................... 207119 Getting the workplanes of a part occurrence in an assembly
................................................................................................................................... 208120 SubOccurrences
................................................................................................................................... 208121 SaveAs function
................................................................................................................................... 209122 Save programatically
................................................................................................................................... 210123 FullDocumentName and GetLocationFoundIn
................................................................................................................................... 211124 Close function, Inventor API
................................................................................................................................... 211125 Making workfeatures of a part invisible in the assembly
................................................................................................................................... 213126 Visibility programatically in Inventor
................................................................................................................................... 213127 AddCustomiPartMember details and tips
................................................................................................................................... 214128 Add in the occurrence of a custom iPart into an assembly
................................................................................................................................... 216129 Occurrences and component definitions
................................................................................................................................... 218130 How to get the parameters of an assembly
................................................................................................................................... 220131 get_Item and Item, what sort of parameter?
................................................................................................................................... 221132 Suppression and Unsuppression of features
................................................................................................................................... 223133 Compute and Suppress from an iPart table programatically
................................................................................................................................... 223134 Skipping missing components programatically
................................................................................................................................... 224135 How to open a document programatically
................................................................................................................................... 224136 Function calls in Autodesk Inventor C++ programming
Autodesk Inventor Programming in C++ by Owen Ransen8
(C) 2021 Owen F Ransen
................................................................................................................................... 225137 Names of objects inside sketches
................................................................................................................................... 225138 COM pointers when programming AutoDesk Inventor
................................................................................................................................... 229139 VARIANT_BOOL
................................................................................................................................... 230140 ParameterPtr and get_XCount
................................................................................................................................... 231141 Gettings objects by name
................................................................................................................................... 233142 How to get the RectangularPatterns in a PartComponentDefinition
................................................................................................................................... 234143 ResultFeatures
................................................................................................................................... 235144 ObjectsEnumerator, a list of objects
................................................................................................................................... 235145 Parameter types
................................................................................................................................... 236146 Face Edge EdgeProxy
................................................................................................................................... 238147 Attributes
................................................................................................................................... 242148 CreateExtrudeDefinition
................................................................................................................................... 242149 Inserting an extrusion in a Part
................................................................................................................................... 244150 Optional parameters and empty COM values
................................................................................................................................... 245151 Points and CenterPoints
................................................................................................................................... 246152 GetTemplateFile
................................................................................................................................... 247153 Add a (planar) sketch to a workplane programatically
................................................................................................................................... 249154 Component Definition
................................................................................................................................... 251155 Adding a workplane to a Part programatically
................................................................................................................................... 253156 Set the visibility of all workplanes in a part
................................................................................................................................... 254157 Listing the names of axes in a part
................................................................................................................................... 255158 get_ActiveDocument
................................................................................................................................... 255159 Get and Set the name of an Inventor document
................................................................................................................................... 257160 The .AddIn file
................................................................................................................................... 258161 Adding a flush constraint programatically
................................................................................................................................... 260162 Adding a flush constraint using workplanes
................................................................................................................................... 262163 Constraints and parts from a programmer's point of view
................................................................................................................................... 263164 Loading your DLL
................................................................................................................................... 264165 Sketches in an Inventor Part
................................................................................................................................... 265166 Default workplanes and default sketches programatically
................................................................................................................................... 268167 Add a work point at a sketch point
................................................................................................................................... 271168 Getting and setting the sketch name (as well as other objects)
................................................................................................................................... 271169 PatternSpacingTypeEnum
................................................................................................................................... 271170 PatternOrientationEnum
................................................................................................................................... 272171 Occurences as Xrefs
................................................................................................................................... 272172 VT_I4
................................................................................................................................... 272173 rgs file for Inventor AddIns, what is it?
................................................................................................................................... 272174 BSTR OLECHAR wchar_t
................................................................................................................................... 274175 AddForSolid
9Contents
(C) 2021 Owen F Ransen
................................................................................................................................... 275176 VBA, VB.NET, C# or C++
................................................................................................................................... 275177 Profiles in sketches programatically
................................................................................................................................... 275178 Creating an Assembly
................................................................................................................................... 278179 Getting the project file location and other options programatically
................................................................................................................................... 281180 regsvr32
................................................................................................................................... 281181 What and where is the AddIn manager?
................................................................................................................................... 282182 RxInventor.tlb
................................................................................................................................... 284183 Adding a rectangle to a sketch programatically
................................................................................................................................... 286184 get_ and Get ?
................................................................................................................................... 286185 UserInterfaceVersion
................................................................................................................................... 287186 Difference between CComPtr and CComQIPtr?
................................................................................................................................... 287187 VARIANT and CComVariant
................................................................................................................................... 288188 Getting items from collections
................................................................................................................................... 289189 Assembly.Document Assembly
................................................................................................................................... 290190 64bit vs 32bit
................................................................................................................................... 290191 Client Graphics
................................................................................................................................... 290192 Hierarchy of objects
................................................................................................................................... 291193 Getting or running an Inventor Instance
................................................................................................................................... 291194 Add a part to an assembly programatically
................................................................................................................................... 294195 Coordinates of a WorkAxis
................................................................................................................................... 295196 Invisibilize components in a collection
................................................................................................................................... 295197 Delete a WorkAxis
................................................................................................................................... 295198 Add a plane by offset from another plane
................................................................................................................................... 300199 Getting hold of the surfaces and faces of a solid object
................................................................................................................................... 302200 Adding an AngleConstraint
................................................................................................................................... 302201 Creating a 64 bit plugin using the Wizard
................................................................................................................................... 303202 Purging Material Assets
................................................................................................................................... 304203 View orientations
................................................................................................................................... 307204 Functions for project files .IPT
................................................................................................................................... 309205 Listing RevolveFeatures of a part programatically
................................................................................................................................... 309206 Create a rectangular pattern of parts programatically
................................................................................................................................... 310207 Suppression and Unsuppression of elements in a pattern
................................................................................................................................... 311208 Accessing mass properties
................................................................................................................................... 312209 Is Excel installed on your computer?
................................................................................................................................... 312210 ConnectToInventor
................................................................................................................................... 313211 gLogger
................................................................................................................................... 314212 iProperties programatically
......................................................................................................................................................... 314iProperties overview
......................................................................................................................................................... 316Listing iProperties of an Inventor document
......................................................................................................................................................... 318iProperties, add a custom value programatically
Autodesk Inventor Programming in C++ by Owen Ransen10
(C) 2021 Owen F Ransen
......................................................................................................................................................... 320iProperties, create a new property set
......................................................................................................................................................... 321iProperties, read the value of a custom property
Part XIII Programming Inventor in C# 322
................................................................................................................................... 3221 Starting Inventor in C#
................................................................................................................................... 3262 MSB3277: Found conflicts between different versions
................................................................................................................................... 3283 C# plugin making
................................................................................................................................... 3324 C# plugins, adding a button and a command
................................................................................................................................... 3385 Button Definition
................................................................................................................................... 3416 C# plugin removal
................................................................................................................................... 3427 C# message box
................................................................................................................................... 3438 Custom iProperties using C#
................................................................................................................................... 3449 Open an Inventor file using C#
................................................................................................................................... 34410 ItemByName for Document
................................................................................................................................... 34411 Get user parameters using C#
................................................................................................................................... 34512 Looping over components inside an assembly in C#
................................................................................................................................... 34713 GetActiveObject does not exist in Marshal
................................................................................................................................... 34714 Calling iLogic from C#
................................................................................................................................... 35115 Listing iLogic rules using C#
................................................................................................................................... 35216 Save programatically in C#
................................................................................................................................... 35317 "Member not found" error in C# add-in
................................................................................................................................... 35518 Browser panes in C#
................................................................................................................................... 35519 Assembly document or part document?
................................................................................................................................... 35620 Listing parameters in an assembly, C#
................................................................................................................................... 35721 Getting the value of a parameter in a part
................................................................................................................................... 35722 Value of a Param
................................................................................................................................... 35823 Getting the GUI language of Inventor
................................................................................................................................... 35824 Changing parameters with C#
................................................................................................................................... 36125 get_Units crashes
................................................................................................................................... 36326 Listing holes in a face of folded metal
................................................................................................................................... 36527 Listing holes in a face of folded metal VB
................................................................................................................................... 37328 Direction of a workaxis
................................................................................................................................... 37429 HoleFeature HoleFeatureProxy C#
................................................................................................................................... 37630 Items in lists by string
................................................................................................................................... 37731 Constrain work axes C#
................................................................................................................................... 37932 Constrain work things of a part to the work things of the containing assembly
................................................................................................................................... 38033 Bounding box of a part
................................................................................................................................... 38034 Matrix Vector and SetTranslation, C#
................................................................................................................................... 38135 WorkPlane orientation in C#
................................................................................................................................... 38536 Standard WorkAxes in C#
11Contents
(C) 2021 Owen F Ransen
................................................................................................................................... 38537 Constrain a part to an assembly level work axis
................................................................................................................................... 38938 Create an assembly document C#
................................................................................................................................... 39239 Listing the profiles of a face in C#
................................................................................................................................... 39540 List all planes in a part, C#
................................................................................................................................... 39741 Get a WorkPlane by name
................................................................................................................................... 39742 kReferenceFeatureObject is a derived part
................................................................................................................................... 39843 Reading values from an iPart table in C#
Part XIV Using Inventor manually 400
................................................................................................................................... 4001 Parallel constraint, not coplanar
................................................................................................................................... 4012 BOMs and Part Lists
......................................................................................................................................................... 401BOM vs Parts List
......................................................................................................................................................... 402Adding a flat parts list in a drawing
......................................................................................................................................................... 402BOM Bill of materials
......................................................................................................................................................... 404Remove something from a Parts List
......................................................................................................................................................... 404Parts list modification
......................................................................................................................................................... 405Parts Only (disabled) problem
......................................................................................................................................................... 406Virtual components
......................................................................................................................................................... 410Parts List Style (Default)
......................................................................................................................................................... 413Alternative to a virtual component in a BOM
................................................................................................................................... 4163 iParts
......................................................................................................................................................... 416iParts general info
......................................................................................................................................................... 417iPart - standard vs custom
......................................................................................................................................................... 417iPart author
......................................................................................................................................................... 417iPart Member and PartNumber
......................................................................................................................................................... 419Custom iParts
......................................................................................................................................................... 422Changing Custom Ipart Parameters
......................................................................................................................................................... 424Suppression of features parametrically using the iPart Author
......................................................................................................................................................... 424Changing from iPart back to normal part
......................................................................................................................................................... 425Custom column in an iPart table
......................................................................................................................................................... 426Create iPart icon is grey
................................................................................................................................... 4264 Suppress and Level Of Detail
................................................................................................................................... 4265 Offset of a point
................................................................................................................................... 4276 Pack And Go
................................................................................................................................... 4297 WorkAxes at assembly level
................................................................................................................................... 4308 Insert constraint
................................................................................................................................... 4339 Faces as objects
................................................................................................................................... 43410 Show hidden lines in a drawing manually
................................................................................................................................... 43511 Axis directions
................................................................................................................................... 43612 Creating folders in the browser manually
................................................................................................................................... 43713 Construction lines in sketches
................................................................................................................................... 43814 Formulas inside parameter settings
................................................................................................................................... 43915 Explode a pattern
................................................................................................................................... 44016 Assembly WorkPoints and Part WorkPoints
................................................................................................................................... 44117 Erase pattern elements
Autodesk Inventor Programming in C++ by Owen Ransen12
(C) 2021 Owen F Ransen
................................................................................................................................... 44218 Axis perpendicular to sketch point, how to
................................................................................................................................... 44519 Delete a dimension manually
................................................................................................................................... 44520 Mass Volume Calculation
................................................................................................................................... 44521 Add a WorkPlane in an Assembly
................................................................................................................................... 44922 Add a feature to an existing pattern
................................................................................................................................... 45023 Add a point to the surface of a tube manually
................................................................................................................................... 45024 General Note and text
................................................................................................................................... 45125 Add an angular dimension
................................................................................................................................... 45226 Adding a Dimension in a sketch
................................................................................................................................... 45227 Application Options Settings
................................................................................................................................... 45228 Backup options for Inventor files
................................................................................................................................... 45329 Add-In automatic load suppression
................................................................................................................................... 45430 Strange material problem
................................................................................................................................... 45531 Browser is missing! Get it back!
................................................................................................................................... 45532 Change material / color of a solid
................................................................................................................................... 45633 Change the offset elevation of a plane
................................................................................................................................... 45734 Changing home view setting
................................................................................................................................... 45835 Changing manipulator snap
................................................................................................................................... 45836 Changing the default units
................................................................................................................................... 45937 Completely and adequately constrained sketches
................................................................................................................................... 46138 Constrain 2 pairs of axes
................................................................................................................................... 46339 Constrain vertically and horizontally
................................................................................................................................... 46540 Contact set
................................................................................................................................... 46541 Contraints between 3D part objects
................................................................................................................................... 46642 Crash when creating a new drawing
................................................................................................................................... 46743 Create a sketch by default on creating a new part
................................................................................................................................... 46744 Creating a big tube with holes in it
................................................................................................................................... 47445 Creating a drawing of an assembly or part
................................................................................................................................... 47546 Creating a workplane offset from another plane
................................................................................................................................... 47647 Customizing the menu
................................................................................................................................... 47748 Delete a parameter
................................................................................................................................... 47749 Deleting, removing a constraint
................................................................................................................................... 47750 Driven Dimensions and their Removal/Change
................................................................................................................................... 47751 Editing a sketch flatly
................................................................................................................................... 47752 Editing Model Parameters and how they are displayed
................................................................................................................................... 47853 Enable and Disable parts and assemblies
................................................................................................................................... 47854 Example of dimensions and parameters in a sketch
................................................................................................................................... 48255 Extruding sketches with multiple concentric circles
................................................................................................................................... 48356 Extruding with widening angles
13Contents
(C) 2021 Owen F Ransen
................................................................................................................................... 48457 File types
................................................................................................................................... 48558 FlipNormal and WorkPlane constraints
................................................................................................................................... 48659 Flush Mate And Axis Constraint Example
................................................................................................................................... 48760 Free Move and Free Rotate
................................................................................................................................... 48761 fx: and parameters and formulas
................................................................................................................................... 48862 Get the browser pane back
................................................................................................................................... 48863 Getting into and out of sketches
................................................................................................................................... 48964 Getting to the constrain icon in Inventor
................................................................................................................................... 48965 Grounded Parts
................................................................................................................................... 49066 Holes in tubes
................................................................................................................................... 49267 How to change the background of the Inventor screen
................................................................................................................................... 49268 How to make a hollow tube
................................................................................................................................... 49369 How to move a 3D object
................................................................................................................................... 49470 Inches problem
................................................................................................................................... 49471 Insert constraint
................................................................................................................................... 49472 Inserting an inclined workplane
................................................................................................................................... 49673 Inventor Apprentice
................................................................................................................................... 49774 Mate vs Flush constraints
................................................................................................................................... 49875 Mini tool bar autofade
................................................................................................................................... 49876 No visible unadaptive sketches
................................................................................................................................... 49877 Pattern inside a sketch
................................................................................................................................... 49978 Patterns (arrays) of features
................................................................................................................................... 50179 Plane on the surface of a tube at an angle
................................................................................................................................... 50280 Problem when inserting iParts into Assemblies
................................................................................................................................... 50381 Problems encountered while executing this command.
................................................................................................................................... 50382 Problems with sketch extrusion and revsurf
................................................................................................................................... 50383 Project files
................................................................................................................................... 50584 Putting 2d dxf files in 3D assemblies, manually
................................................................................................................................... 50585 Removing material with the cut extrusion command
................................................................................................................................... 50686 HealthStatusEnum
................................................................................................................................... 50787 Showing dimensions temporarily
................................................................................................................................... 50788 Showing expressions in a sketch
................................................................................................................................... 50789 Sketch plane
................................................................................................................................... 50790 Sketches and Features
................................................................................................................................... 50991 Suppression and mirrored features
................................................................................................................................... 50992 Templates and Template files
................................................................................................................................... 51193 The Marking Menu
................................................................................................................................... 51294 Trim and Fillet
................................................................................................................................... 51395 ul as a dimension
Autodesk Inventor Programming in C++ by Owen Ransen14
(C) 2021 Owen F Ransen
................................................................................................................................... 51396 Units, Inches, Mm
................................................................................................................................... 51397 Vault
................................................................................................................................... 51398 View face command
................................................................................................................................... 51399 Viewing Multiple Documents in Inventor
................................................................................................................................... 514100 Work Axis Thru Circular Hole
................................................................................................................................... 515101 Work Point in center of a hole (COPY)
................................................................................................................................... 515102 Workplanes and Sketches, Creating a sketch on an arbitrary plane
................................................................................................................................... 517103 WorkPoint in center of a hole
................................................................................................................................... 518104 Yellow Dot Green Dot Constraints
Part XV Acknowledgements 518
Index 520
15Autodesk Inventor Programming in C++
(C) 2021 Owen F Ransen
1 Autodesk Inventor Programming in C++
Inventor Programming in C++
Contact Owen Ransen at help@ransensoftware.com for more details.
2 0) Installing the SDK
After you have installed Inventor you'll have a directory like this:
C:\Users\Public\Documents\Autodesk\Inventor 2019\SDK
or something very similar.
16 Autodesk Inventor Programming in C++ by Owen Ransen
(C) 2021 Owen F Ransen
Click on the DeveloperTools.msi . UserTools.msi has real toolstogether with source code, so maybe good for looking at samples.
Once you have installed the SDK you'll find another .msi file for theWizards which create application skeletons for you. It will besomewhere like this:
C:\Users\Public\Documents\Autodesk\Inventor 2019\SDK\DeveloperTools\Tools\Wizards\InventorWizards.msi
Visually:
170) Installing the SDK
(C) 2021 Owen F Ransen
Note also the trickeries of RxInventor.
3 1) How to use this help file (READ THIS FIRST)
Please read this first.
You should read in sequence the numbered parts 1) to 7), startingwith this one. These will give you a brief rough overview of theInventor API.
Then you should use the index (at the top of the contents page) tofind answers to specific questions as they pop up when you createyour own Autodesk Inventor C++ programs.
Apart from this brief introduction, this help file is a set of codefragments, nothing more.
You can contact me, Owen Ransen, at help@ransensoftware.com.
I've also included tips on Using Inventor Manually. You may be aprogrammer, but you do need how to use Inventor as a normal userbefore you can hope to program it! There are a ton of tutorials outthere about using Inventor. If neccessary please do at least some ofthem before attempting the rest of this book.
The code fragments are designed to help you understand how to dothings. Some of them are identical to functions in my Inventor helperlibrary. The library is updated more often than this text, ask me if youwant the sources of the library.
Compilation error codes are included in the index. If you get C2064then there may be an explanation in this help file. Use the index forC2064.
You need to be a decent C++ programmer and have a good workingknowledge of Windows MFC .
Now, go to 2) Introduction.
18 Autodesk Inventor Programming in C++ by Owen Ransen
(C) 2021 Owen F Ransen
4 2) Introduction
If you've decided to program Inventor in C++ you can do it in manydifferent ways, but basically either you create an AddIn (not coveredhere) or you create an external exe file. See the diagrams below:
Both systems use the COM interface, and this book is useful for bothtypes. However this book covers the external EXE solution usingC++. Since both methods use the COM interface most of this book isapplicable to both types of application.
If you are not familiar with the COM interface don't worry, I give lots ofexamples, explanations and tips on its use.
I use Visual Studio 2015, C++ with MFC, and so do the examplesources.
3) Connecting to Inventor from a Windows MFC app.
5 3) Connecting to Inventor from a Windows MFC app.
Here is what your init of you MFC Windows application could looklike:
BOOL CCollMakeApp::InitInstance(){
193) Connecting to Inventor from a Windows MFC app.
(C) 2021 Owen F Ransen
INITCOMMONCONTROLSEX InitCtrls;InitCtrls.dwSize = sizeof(InitCtrls);// Effettuare questa impostazione in modo da includere tutte le classi
di controlli comuni da utilizzare// nell'applicazione.InitCtrls.dwICC = ICC_WIN95_CLASSES;InitCommonControlsEx(&InitCtrls);
::CoInitialize (NULL) ;
if (!ExcelIsPresent()) { // Required if you use tabular iParts gLogger.Printf (ekErrMsg,L"Is Excel installed for Inventor?") ; }
const bool kbInventorOK = ConnectToInventor();
if (!kbInventorOK) { return FALSE ; }
CWinApp::InitInstance();
// Creare il gestore della shell se la finestra di dialogo contiene// controlli della visualizzazione elenco o struttura ad albero della
shell.CShellManager* pShellManager = new CShellManager;
// Initialization finished, run the main dialog of the application... {
CMainDlg dlg; m_pMainWnd = &dlg; (void)dlg.DoModal();
}
// Program finished, tidy up...
// Let the user see dialogs etc... GetInvAppPtr()->SilentOperation = VARIANT_FALSE ;
// Free up Inventor interface globals DestroyInventorGlobals () ;
::CoUninitialize();
// Eliminare il gestore della shell creato in precedenza.if (pShellManager != NULL){
delete pShellManager; }
return FALSE;}
20 Autodesk Inventor Programming in C++ by Owen Ransen
(C) 2021 Owen F Ransen
CoInitialize and CoUninitialize are required to be able to use COMand its pointers. What I do is, in sequence:
1. CoInitialize starts up COM and COM pointer handling.2. CreateInventorGlobals, sets up things useful to me as my Inventor
program is running. It also starts Inventor running.3. dlg.DoModal would be a dialog with buttons which the user can use
to make objects with the Inventor API.4. DestroyInventorGlobals tidies up my pointers after the dialog has
finished (i.e. when I come out of DoModal).5. ::CoUninitialize for the final tidy up of the COM pointers and
interface
Step 3 above is the heart of the program, a dialog box which talks toInventor. You have to write that!
4) Inventor pointers and DestroyInventorGlobals
6 4) Pointers to Inventor and useful Inventor API objects.
In the library, file InventorSupp.cpp there are these pointers:
static CComPtr<Application> pInvApp = nullptr;static CComPtr<TransientGeometry> pTransGeom = nullptr;static CComPtr<TransientObjects> pTransientObjects = nullptr;static CComPtr<Matrix> pIdMatrix = nullptr;
pInvApp is initialised by a call to ConnectToInventor.
The last three are initialised as required, for example:
CComPtr<TransientGeometry> GetTransGeomPtr (){ if (pInvApp == nullptr) { gLogger.Printf (ekErrMsg,L"GetTransGeomPtr failed, no app") ;
214) Pointers to Inventor and useful Inventor API objects.
(C) 2021 Owen F Ransen
return nullptr ; }
if (pTransGeom == nullptr) { // Not yet initialised... pInvApp->get_TransientGeometry(&pTransGeom); }
if (pTransGeom == nullptr) { // Something went wrong gLogger.Printf (ekErrMsg,L"CCollMakeApp::GetTransGeomPtr failed, notransient geometry") ; return nullptr ; }
return pTransGeom ;}
The Inventor application pointer is the main method for getting datafrom Inventor and sending commands to it.
The transient geometry pointer lets you create matrices, vectors etc.Explained more here.
The transient objects pointer is used to make temporary collections ofobjects you need to operate on, for example a list of holes in a solidobject or some workplanes arranged somewhere in a part. TransientObjectCollections are explained more here.
And pIdMatrix is an often used object, so rather than creating it everytime its need I create it once and use it often.
DestroyInventorGlobals should be called at the end of your program:
void DestroyInventorGlobals() { // These are smart pointers and setting them to nullptr will release thememory too... pInvApp = nullptr ; pTransGeom = nullptr ; pTransientObjects = nullptr ; pIdMatrix = nullptr ;}
5) Running Inventor programatically.
22 Autodesk Inventor Programming in C++ by Owen Ransen
(C) 2021 Owen F Ransen
7 5) Running Inventor programatically
Inventor has to be running before you can get at objects inside it. ConnectToInventor will try to run Inventor if it is not already running.
On some computers starting Inventor can take several seconds.
This is what actually starts Inventor:
hRes = CoCreateInstance (InvAppClsid, NULL, CLSCTX_LOCAL_SERVER, __uuidof(IUnknown), (void **) &pInvAppUnk); if (FAILED (hRes)){ pInvApp = nullptr ; ShowCOMError (hRes,L"ConnectToInventor,CoCreateInstance failed") ; return false; }
If you are not familiar with COM have a quick read of this explanationof the FAILED macro, and other HRESULT codes and macros.
The function ReturnAndShowCOMError is used to give you moreinformation about any failure, and to return the fail code. More here.
6) Creating a part document and a sketch
8 6) Creating a part document and a sketch
The first thing most users do with Inventor is to create a sketch insidea part document. Here is my function for creating a new Partdocument in Inventor:
HRESULT CreateNewPartDoc(CComPtr<Application> pInventorApp, CComPtr<PartDocument> &pPartDoc, const wchar_t* const pszPartName){ HRESULT hr = S_OK;
CComVariant pSubDocType; CComBSTR sTemplate;
236) Creating a part document and a sketch
(C) 2021 Owen F Ransen
hr = pInventorApp->GetTemplateFile (kPartDocumentObject, // We arecreating a PartDocument kMetricSystemOfMeasure, // mm kDefault_DraftingStandard, pSubDocType, &sTemplate);
if(hr != S_OK) { return hr; }
gLogger.Printf(ekLogMsg, L"Template file is <%s>\n", CString(sTemplate));
CComPtr<Document> pDoc; hr = pInventorApp->Documents->Add (kPartDocumentObject, sTemplate, VARIANT_TRUE, &pDoc);
if (hr != S_OK) { return hr; }
pPartDoc = CComQIPtr<PartDocument>(pDoc);
if ((pszPartName != nullptr) && (wcslen (pszPartName) > 0)) { BSTR bstrName ; pDoc->get_DisplayName (&bstrName) ; pPartDoc->DisplayName = pszPartName ; pDoc->get_DisplayName (&bstrName) ; ::SysFreeString (bstrName) ; }
return hr;}
I'm assuming that we will always use wide char, wchar_t, UNICODEor CStrings for our string data. In the function above the part name ispassed as a wchar_t pointer.
A "part" is usually a collection if solid objects with holes or cuts orextrusions. An assembly is usually a collection of parts, or moreformally a set of occurrences of parts. See here for the file types inInventor.
Unfortunately, the part document isn't really where all the "stuff" is. Allthe "stuff" is inside a PartComponentDefinition:
24 Autodesk Inventor Programming in C++ by Owen Ransen
(C) 2021 Owen F Ransen
As you can see the PartComponentDefinition contains a lot of lists,and one of the lists contains sketches, and we'll create a new sketchin that list. But before we do that we have to get hold of thePartComponentDefinition. That is done like this:
// Get the component definition of the part, where all the"stuff" is... CComPtr<PartComponentDefinition> pPartCompDef = nullptr ; hRes = pPartDoc->get_ComponentDefinition(&pPartCompDef) ; if (FAILED(hRes) || (pPartCompDef == nullptr)) { ShowCOMError (hRes,L" get_ComponentDefinition failed."); }
I'll go into some detail about the these four lines because theyillustrate how the Inventor API, C++ and COM talk to each other.
Many of the variables in C++ programs using COM are smartpointers. In the above example the smart pointer is pPartCompDef.Using smart pointers like this means that you don't need to allocateand deallocate them explicitly, it is all done by the smartness of the
256) Creating a part document and a sketch
(C) 2021 Owen F Ransen
pointer. So when we do this:
CComPtr<PartComponentDefinition>pPartCompDef = nullptr ;
we don't need to delete or release pPartCompDef after use, it will allhappen automatically when the pointer goes out of scope.
Also note that I've initialised it to nullptr. This is my own personalstyle, it means it is initialised even if I forget to call a function toinitialise it.
In general many functions we call in the Inventor API take theaddress of a pointer and initialise it, as well as returning a status. Forexample:
hRes = pPartDoc->get_ComponentDefinition(&pPartCompDef) ;
pPartCompDef will be initialised to point at an object, and you'll get areturn value placed in hRes. Why two return values? Because insome circumstances the pointer returned can be validly nullptr. hResmight return S_OK, because the function did not fail, but the pointercould still be nullptr because the object you were looking for does notexist. It is for that reason that I always look at both return values:
if (FAILED(hRes) || (pPartCompDef == nullptr)) {
Click here for more about S_OK, HRESULT and FAILED.
7) Some tips...
9 7) Some tips for Autodesk Inventor C++ programmers
Here are some tips, in no particular order, I've found useful whenprogramming AutoDesk Inventor in C++
Tip1) Check your return values, hRes and COM pointers etc. I know itmakes your code look messy, but you are flying blind otherwise. Ifspeed is really a problem then take the out the checks only at thevery end of the development.
26 Autodesk Inventor Programming in C++ by Owen Ransen
(C) 2021 Owen F Ransen
Tip 2) Make sure that you know how to do manually what you aretrying to do programatically. Else you may end up trying to debugsource code when you should be debugging the manual method.
Tip 3) Name objects sensibly. "Part1" and "Assemby3" are less usefulwhen debugging than "InnerTube" and "MainBikeAssembly".
Tip 4) Don't do programatically what may be easier to do by hand. Forexample you can make a parametric object by hand and simplychange the parameters with your program.
Tip 5) If you know VB or C# then when in difficulty test using thoselanguages. These are far more interactive than C++, even with theIDE.
27Right hand coordinate system
(C) 2021 Owen F Ransen
10 Right hand coordinate system
It seems like Inventor uses the right hand coordinate system:
(Not left hand)
11 iLogic and VBA
11.1 iLogic editing
You can create new iLogic rules or edit existing ones like this:
28 Autodesk Inventor Programming in C++ by Owen Ransen
(C) 2021 Owen F Ransen
11.2 iLogic and suppression of parts in assemblies
This has some useful info...
http://inventbetter.blogspot.com/2012/01/setting-level-of-detail-with-ilogic.html
...but basically you need a custom level of detail to be present andactive if you want to suppress parts inside assemblies with iLogic.
Setting the Level of Detail with iLogic
iLogic requires a custom Level of Detail (LoD) before it can performan operation that suppresses a component. If a custom LoD is notactive or one does not exist you will get an error message. I get a lotof enquires about this dialog box and how one can avoid the hassle.
29iLogic and VBA
(C) 2021 Owen F Ransen
First create a rule called “LoD” and populate with the following code:
Dim doc as AssemblyDocument = ThisDoc.Document Dim oLOD As LevelOfDetailRepresentation Dim oAsmCompDef As ComponentDefinition oAsmCompDef = doc.ComponentDefinitionTry oLOD = oAsmCompDef.RepresentationsManager.LevelOfDetailRepresentations.Item("iLogic").Activate(True)Catch Dim nLOD As LevelOfDetailRepresentation nLOD = oAsmCompDef.RepresentationsManager.LevelOfDetailRepresentations.Add("iLogic") oLOD = nLODFinally oLOD = oAsmCompDef.RepresentationsManager.LevelOfDetailRepresentations.Item("iLogic").Activate(True)End Try
11.3 Run an EXE from inside an iLogc rule
Here is an example:
Sub Main()
Dim sProgramName As String Dim sArgument As String Dim Q As String Q=Chr(34) ' Quote character
sProgramName = "C:\PLMProgs\Simu.Exe"
' Note that "Latest Working" must have quotes around it in thisexample... sArguments = " Ransen.IAM " & Q & "Latest Working" & Q
Call Shell(sProgramName & " " & sArguments, vbNormalFocus)End Sub
Note that when you exit the iLogic editor Inventor will try to run theprogram
30 Autodesk Inventor Programming in C++ by Owen Ransen
(C) 2021 Owen F Ransen
11.4 iLogic suppression of features in a part
Here's an example:
If Assecondo < 1000 Then Feature.IsActive ("Extrusion4") = FalseElse Feature.IsActive ("Extrusion4") = TrueEnd If
Assecondo is a parameter and "Extrusion4" is a feature in an iPart.But suppression is only for LOD (level of detail) stuff.
11.5 iLogic and part parameters
I think this is how you access them:
If Parameter("Bombato") Then ' do somethingElse ' do something elseEnd If
31iLogic and VBA
(C) 2021 Owen F Ransen
11.6 iLogic to delete suppressed compoents
Here's how to do it, ignoring occurrences in patterns.
Trace.WriteLine(" Starting....")
Dim oComp As ComponentOccurrenceDim oComps As ComponentOccurrences
oComps = ThisDoc.Document.ComponentDefinition.Occurrences
For Each oComp In oComps If oComp.Suppressed Then Trace.WriteLine(oComp.Name + " is suppressed")
If Not oComp.IsPatternElement Then oComp.Delete
End If Else
Trace.WriteLine(oComp.Name + " NOT suppressed")
End If Next
11.7 iLogic debugging statements, Trace
You need to download DebugView which is a Microsoft debugstatement monitor. Then, inside iLogic, and maybe VBA, you'll seethe Trace statements.
32 Autodesk Inventor Programming in C++ by Owen Ransen
(C) 2021 Owen F Ransen
Here's an example Trace statement in an iLogic macro:
Trace.WriteLine(oComp.Name + " is suppressed")
33iLogic and VBA
(C) 2021 Owen F Ransen
11.8 iLogic to change dimensions in sketches
It is a bit tricky but you can add a new rule and inside that rule set thenamed dimensions and parameters.
Inside a part add a rule. Here is an example, Blue words areparameters/dimensions from the part or sketch, so this block uses thetwo objects (DiamColl and DiamAtt) to change a diameter called Dcoll .
Dim RagColl as DoubleDim RagAtt As DoubleRagColl = DiamColl/2.0RagAtt = DiamAtt/2.0If RagAtt < RagColl Then Dcoll = Sqrt((RagColl*RagColl) - (RagAtt*RagAtt))Else Dcoll = 0.0 End If
What is also a bit tricky is when things get triggered.
11.9 iLogic to add parts to an assembly
Here you go, follow the comments...
Dim sExcelFileName As String = "Pippo.xlsx"Dim oPath As StringDim Row2 As String '= RowDim Rowchange2 As String '= RowchangeDim text2 As String = x1Dim text3 As String = x1
'file path to useoPath = ThisDoc.Path & "\"'file to useoFile = "40050457.ipt"
' set a reference to the assembly component definintion.' This assumes an assembly document is open.Dim oAsmCompDef As AssemblyComponentDefinitionoAsmCompDef = ThisApplication.ActiveDocument.ComponentDefinition
' These four lines create a matrix, which has default values scale 1 andpos 0,0,0Dim oTG As TransientGeometryoTG = ThisApplication.TransientGeometryDim oMatrix As MatrixoMatrix = oTG.CreateMatrix
34 Autodesk Inventor Programming in C++ by Owen Ransen
(C) 2021 Owen F Ransen
'Iterate through all of the occurrencesDim oOccurrence As ComponentOccurrence
Dim i As Integer
For i = 2 To 6 ' Form the cell address text2="C" + String.Format(i,"#")
oFile = GoExcel.CellValue(sExcelFileName, "Sheet1",text2)
'place an instance of the component 'in this case at 0,0,0
oOccurrence = oAsmCompDef.Occurrences.Add(oPath & oFile, oMatrix) oOccurrence.Grounded = False
Next
11.10 iLogic iProperties example
Here you go:
Option Explicit
Public Sub Main()
' Get the Documents collection object. Dim invDocs As Documents invDocs = ThisApplication.Documents Dim sExt As String ' Iterate through the contents of the Documents collection. Dim invDocument As Document Dim SubDoc As Document Dim Asm As AssemblyDocument Dim DocsInAsm As DocumentsEnumerator Dim SubDocAsAsm As AssemblyDocument For Each invDocument In invDocs ' Display the full filename of the document in the Immediatewindow. If invDocument.DocumentType = kAssemblyDocumentObject Then Asm = invDocument DocsInAsm = Asm.AllReferencedDocuments MessageBox.Show ("Assembly " & invDocument.FullFileName & "has " & DocsInAsm.Count & " sub documents") ListUserParameters (Asm) End If Next
End Sub
35iLogic and VBA
(C) 2021 Owen F Ransen
Private Sub ListUserParameters(ByRef Asm As AssemblyDocument) Dim oDef As AssemblyComponentDefinition Dim AsmUserParams As UserParameters Dim AsmUserParam As UserParameter Dim doc As Document doc = ThisApplication.ActiveDocument
' Get the custom property set. Dim customPropSet As PropertySet customPropSet = doc.PropertySets.Item("Inventor User DefinedProperties")
Dim customProp As Object
customProp = customPropSet.Item ("CIRCUITS")
oDef = Asm.ComponentDefinition AsmUserParams = oDef.Parameters.UserParameters For Each AsmUserParam In AsmUserParams ' Debug.Print ("param is <" & UserParam.Name & ">") If AsmUserParam.Name = "CIRCUITS" Then MessageBox.Show ("CIRCUITS = " & AsmUserParam.ModelValue)
customProp.Value = AsmUserParam.ModelValue End If Next End Sub
Enter topic text here.
11.11 Local or global VBA?
Whether the VBA functions you make are local or global depends onwhere they are written:
36 Autodesk Inventor Programming in C++ by Owen Ransen
(C) 2021 Owen F Ransen
Enter topic text here.
11.12 Listing documents open in Inventor with VBA
Here is some VBA code to do that to the VBA editor window. It alsolists the documents inside the top level documents:
Option Explicit
Public Sub ShowDocuments2()
' Get the Documents collection object. Dim invDocs As Documents Set invDocs = ThisApplication.Documents Dim sExt As String ' Iterate through the contents of the Documents collection. Dim invDocument As Document Dim SubDoc As Document Dim Asm As AssemblyDocument Dim DocsInAsm As DocumentsEnumerator For Each invDocument In invDocs ' Display the full filename of the document in the Immediate window. sExt = Right(invDocument.FullFileName, 3) If sExt = "IAM" Then Set Asm = invDocument
37iLogic and VBA
(C) 2021 Owen F Ransen
Set DocsInAsm = Asm.AllReferencedDocuments Debug.Print "Assembly " & invDocument.FullFileName & " has " & DocsInAsm.Count & " sub documents" For Each SubDoc In DocsInAsm Debug.Print " SubDoc " & SubDoc.FullFileName Next End If Next
End Sub
11.13 VBA document type
There is .Type and .DocumentType, you need to use the latter:
Public Sub ShowDocuments2()
' Get the Documents collection object. Dim invDocs As Documents Set invDocs = ThisApplication.Documents ' Iterate through the contents of the Documents collection. Dim invDocument As Document For Each invDocument In invDocs ' Display the full filename of the document in the Immediate window.
Select Case invDocument.DocumentType Case DocumentTypeEnum.kAssemblyDocumentObject Debug.Print "IAM " + invDocument.FullFileName
Case Else Debug.Print "OTHER " + invDocument.FullFileName
End Select Next
End Sub
38 Autodesk Inventor Programming in C++ by Owen Ransen
(C) 2021 Owen F Ransen
11.14 Inventor VBA and Excel
To use Excel from a VBA Macro in Inventor you need to add areference:
...else you'll get a
user defined type not defined
...error message.
11.15 Update custom iproperty with VBA and iLogic
This function will do that, but note how it must be called (with aVariant, not with a string or integer):
' Note that the third parameter must be a Variant, not an integer or stringPublic Sub UpdateCustomiProperty(ByRef Doc As Document, ByRef PropertyName As String, ByRef PropertyValue As Variant) ' Get the custom property set. Dim customPropSet As PropertySet Set customPropSet = Doc.PropertySets.Item("Inventor User Defined Properties")
' Get the existing property, if it exists. Dim prop As Property On Error Resume Next ' How we know if the iProperty already exists
39iLogic and VBA
(C) 2021 Owen F Ransen
Set prop = customPropSet.Item(PropertyName)
' Check to see if the above call failed. If it failed ' then the property doesn't exist. If Err.Number <> 0 Then ' Failed to get the existing property so create a new one. Call customPropSet.Add(PropertyValue, PropertyName) Debug.Print ("Property does not exist so adding it") Else ' Change the value of the existing property. prop.Value = PropertyValue Debug.Print ("Property exists,just changing it to " & prop.Value) End If End Sub
11.16 Shared global variables in iLogic
When declaring variables in an iLogic rule, that variable is onlyaccessible within the context of that rule. If you need to create avariable and set its value to use within numerous rules, then SharedVariables are the answer.
' Declaring shared variablesSharedVariable("VariableName") = "This is the value" SharedVariable("cylinderHeight") = Parameter("CylinderHeight")
Once a Shared Variable has been declared and a value provided,then it can be consumed and updated as necessary.
' Using shared variables Dim cylinderHieght As Double = SharedVariable("cylinderHeight")
11.17 Declaring variables in iLogic
I've found this helpful:
https://www.autodesk.com/autodesk-university/article/iLogic-Best-Practices-and-Fundamentals-for-Success
They recommend explicitly declaring variables, like this:
40 Autodesk Inventor Programming in C++ by Owen Ransen
(C) 2021 Owen F Ransen
Dim cylinderHeight As Double = Parameter("CylinderHeight")Dim fileName As String = "This is a string value!"Dim holeCount As Integer = 2Dim occurrenceName As String = String.EmptyDim plateWidth As Double = Nothing
11.18 iLogic dialog form modification
Here's how to modify an existing iLogic form:
11.19 iLogic, adding a new form
Right click in the iLogic tab, but not on an existing button. ChooseAdd Form and you'll get this:
41iLogic and VBA
(C) 2021 Owen F Ransen
Drag a rule from the left of the into the list of controls to add a rule asa button.
11.20 When do iLogic rules run?
It seems that if an iLogic rule contains a parameter in its text then ifthat parameter is changed then the rule is run.
The rule called FinBlock will be run whenever the parameterFinBlockMaterial is changed:
43iLogic and VBA
(C) 2021 Owen F Ransen
11.21 Inventor from inside Access
Here is what I use:
Dim invApp As Inventor.Application
Public Function GetInventorApp() As Inventor.Application
' This is an essential part beause GetObject could throw an exceptionOn Error GoTo InvMissing
If Not invApp Is Nothing Then Debug.Print "InvApp already ok" Set GetInventorApp = invApp Exit Function End If
'try to get open instance of Excel Application Set invApp = GetObject(, "Inventor.Application") 'tries to retrieve running instance of Inventor Set GetInventorApp = invApp Debug.Print "InvApp found ok " Exit Function InvMissing: ' We hope that GetObject has thrown an exception only because Inventor is not already running Set invApp = CreateObject("Inventor.Application") If invApp Is Nothing Then Call MsgBox("Failed to Get or Create Inventor Application instance. Exiting.", , "") Else Debug.Print "InvApp created ok " End If End Function
44 Autodesk Inventor Programming in C++ by Owen Ransen
(C) 2021 Owen F Ransen
11.22 Custom iProperties in component with VBA
Here is an example:
Dim Inv As Inventor.Application Set Inv = GetInventorApp() Dim invAsm As Inventor.AssemblyDocument Set invAsm = Inv.Documents.Open(sComponentFullFileName) ' from iProperties ' CC_FIN_GEOMETRY ' CC_NUM_RANGHI ' TC_NAME = T014_R006_N014_T55_E02R_U01R_V1_V02 Set PropSet = invAsm.PropertySets.Item("Inventor User Defined Properties") sGeom = PropSet.Count For p = 1 To PropSet.Count If PropSet.Item(p).Name = "CC_NUM_RANGHI" Then iNumRanghi = PropSet.Item(p).Value ElseIf PropSet.Item(p).Name = "CC_FIN_GEOMETRY" Then sGeom = PropSet.Item(p).Value ElseIf PropSet.Item(p).Name = "TC_NAME" Then sTcName = PropSet.Item(p).Value End If Next p Debug.Print "G= <" & sGeom & ">, numranghi = <" & iNumRanghi & ">"
12 Programming Inventor in C++
Click on the book icon to the left to open this section.
45Programming Inventor in C++
(C) 2021 Owen F Ransen
12.1 Get the name of a part
See also GetOccurenceName
First note the difference between DisplayName and PartName:
If you have the occurrence of a part you can get the display name of it(with its :count part), the filename, like this:
CComPtr<ReferencedFileDescriptor> pRefFileDescA = pOccA->ReferencedFileDescriptor ; CComBSTR bstrAName; HRESULT hRes = pRefFileDescA->get_DisplayName (&bstrAName) ; CString csAName ; if (SUCCEEDED(hRes)) { csAName = CString (bstrAName) ; }
If you have a part component definition:
CString GetPartName (CComPtr<PartComponentDefinition>&pPartCompDef){ CString csPartName; CComPtr<Document> pDocument; HRESULT hRes =pPartCompDef->get_Document((IDispatch**)&pDocument);
if (FAILED(hRes)) { ShowCOMError(hRes, L"Could not get part name pDocument"); return csPartName; }
46 Autodesk Inventor Programming in C++ by Owen Ransen
(C) 2021 Owen F Ransen
CComBSTR bstrPartName; hRes = pDocument->get_DisplayName(&bstrPartName);
if (FAILED(hRes)) { ShowCOMError(hRes, L"Could not get part name displayname"); return csPartName; }
csPartName = CString (bstrPartName) ;
return csPartName;}
12.2 Zoom
// This will zoom all the current document...void ZoomAll(){ CComPtr<Application> pInvApp = GetInvAppPtr () ; if (pInvApp == nullptr) { return ; }
CComPtr<Document> pCurrentDoc ; HRESULT hRes = pInvApp->get_ActiveDocument (&pCurrentDoc) ; if (FAILED(hRes)) { return ; }
CameraPtr pCam = pInvApp->ActiveView->Camera ; pCam->Fit() ; pCam->Apply () ;}
12.3 GetWorkPlaneName GetOccurrenceName
These two functions are useful when your constraints do not work:
CString GetWorkPlaneName(CComPtr<WorkPlane>& pWorkPlaneA){ CString csWPName; if (pWorkPlaneA != nullptr) { csWPName = CString(pWorkPlaneA->Name.GetBSTR()); }
47Programming Inventor in C++
(C) 2021 Owen F Ransen
return csWPName;}
/**********************************************************************************************/
// This actually gets the name of the document being referencedby the occurrence// It could be something like "3312345.IPT" CString GetOccurrenceName(CComPtr<ComponentOccurrence>& pOcc){ CString csOccName ;
if (pOcc != nullptr) { CComPtr<ReferencedFileDescriptor> pRefFileDesc = pOcc->ReferencedFileDescriptor ; CComBSTR bstrAName; pRefFileDesc->get_DisplayName (&bstrAName) ; csOccName = CString (bstrAName) ; }
return csOccName;}
/**********************************************************************************************/
12.4 Investigating Asset Libraries Progamatically
You can loop over all the asset libraries loaded into Inventor like this:
CComPtr<AssetLibraries> pAssLibs ; HRESULT hRes = pInvApp->get_AssetLibraries (&pAssLibs) ; if (FAILED(hRes) || (pAssLibs == nullptr)) { ShowCOMError (hRes,L"Could not get asset libraries"); return ; }
long iNumAssLibs ; pAssLibs->get_Count(&iNumAssLibs) ; WalertBoxA ("There are %d asset libraries",iNumAssLibs) ;
for (long iLib = 1 ; iLib <= iNumAssLibs ; iLib++) { CComPtr<AssetLibrary> pAssLib ; pAssLibs->get_Item (CComVariant(iLib),&pAssLib) ;
48 Autodesk Inventor Programming in C++ by Owen Ransen
(C) 2021 Owen F Ransen
CComBSTRbstrDisplayName,bstrFullFileName,bstrInternalName ; pAssLib->get_DisplayName (&bstrDisplayName) ; pAssLib->get_FullFileName (&bstrFullFileName) ; pAssLib->get_InternalName (&bstrInternalName) ;
TRACE (L"Lib %d has <%s>, <%s>, <%s>.\n",iLib,bstrDisplayName,bstrFullFileName,bstrInternalName); }
And you'll get a result something like this:
Lib 1 has <Autodesk Material Library>, <C:\Program Files (x86)\Common Files\AutodeskShared\Materials\2015\PhysicalMaterial.adsklib>, <AD121259-C03E-4A1D-92D8-59A22B4807AD>.Lib 2 has <Autodesk Appearance Library>, <C:\Program Files (x86)\Common Files\AutodeskShared\Materials\2015\assetlibrary_base.adsklib>, <314DE259-5443-4621-BFBD-1730C6CC9AE9>.Lib 3 has <Favorites>, <C:\Users\Owen\AppData\Roaming\Autodesk\Inventor2015\FavoriteMaterials.adsklib>, <D07F930C-485A-4658-AD69-C91D17FEB99B>.Lib 4 has <Inventor Material Library>, <C:\Users\Public\Documents\Autodesk\Inventor2015\Design Data\Materials\InventorMaterialLibrary.adsklib>, <AFEFC330-5E61-4E24-814F-AE810148B79D>.
The internal name is a GUID it looks like.
Note that it seems that you need to have loaded at least one part,else the assets can be null pointers. It seems like loading a part loadsthe materials.
Once you have an asset lib you can loop over its contents like this:
CComPtr<AssetsEnumerator> pAssEnum ; pAssLib->get_MaterialAssets (&pAssEnum) ;
const long ikNumAssets = pAssEnum->Count ;
for (long iAss = 1 ; iAss <= ikNumAssets ; iAss++) { CComPtr<Asset> pAsset ; pAssEnum->get_Item (CComVariant(iAss),&pAsset) ;
CComBSTR bstrDispName,bstrName,bstrCatName ; pAsset->get_DisplayName (&bstrDispName) ; pAsset->get_Name (&bstrName) ; pAsset->get_CategoryName (&bstrCatName) ; TRACE (L" DisplayName=<%s> Name=<%s> CatName=<%s>\n", bstrDispName,bstrName,bstrCatName) ; }
49Programming Inventor in C++
(C) 2021 Owen F Ransen
And the results will look something like this:
DisplayName=<GFRC> Name=<Material-010> CatName=<Concrete> DisplayName=<Gold> Name=<Material-068> CatName=<Metal> DisplayName=<Iron, Ductile> Name=<Material-071> CatName=<Metal> DisplayName=<Lead> Name=<Material-072> CatName=<Metal> DisplayName=<Silver> Name=<Material-076> CatName=<Metal> DisplayName=<Steel> Name=<Material-077> CatName=<Metal> DisplayName=<Steel, Galvanized> Name=<Material-079> CatName=<Metal>
I think the display name will change from language to language, but Ineed to investigate further. Categories are clearly Metal, Concrete,Wood etc.
12.5 Bounding box of a part occurrence in an assembly
This is probably what you are looking for:
BoxPtr pBox = pOcc->RangeBox ; PointPtr Min = pBox->GetMinPoint () ; PointPtr Max = pBox->GetMaxPoint () ;
12.6 Parallel planes programatically
The software way of doing this...
50 Autodesk Inventor Programming in C++ by Owen Ransen
(C) 2021 Owen F Ransen
...is illustrated below:
/*Given two occurrences which contain workplanes to be flush constrained togetherthis function creates a flush constraint between them*/bool AddFlushConstraintOfTwoPlanes (CComPtr<AssemblyComponentDefinition>& pAsmCompDef, CComPtr<ComponentOccurrence>& pOccA, CComPtr<WorkPlane>& pWorkPlaneA, CComPtr<ComponentOccurrence>& pOccB, CComPtr<WorkPlane>& pWorkPlaneB, const double kOffsetMm, /*=0.0*/ const wchar_t* const pszConstraintName /*=nullptr*/, const double kmmMax /*= 0.0*/){ CComPtr<WorkPlaneProxy> pWPProxyA ; HRESULT hRes = pOccA->CreateGeometryProxy (pWorkPlaneA,(IDispatch**)&pWPProxyA) ; if (FAILED(hRes)) { ShowCOMError (hRes,L"AFCOTP could not get pWPProxyA.") ; return false ; }
CComPtr<WorkPlaneProxy> pWPProxyB ; pOccB->CreateGeometryProxy (pWorkPlaneB,(IDispatch**)&pWPProxyB) ; if (FAILED(hRes)) { ShowCOMError (hRes,L"AFCOTP could not get pWPProxyB.") ; return false ; }
// Get the list of constraints of the assembly so you can add a new one CComPtr<AssemblyConstraints> pConstraintList ; hRes = pAsmCompDef->get_Constraints(&pConstraintList) ; if (FAILED(hRes)) { ShowCOMError (hRes,L"AFCOTP could not get constraints.") ; return false ; }
CComVariant varOffset(kOffsetMm/10.0); // Convert to offset in cm CComPtr<FlushConstraint> pFlushConstraint ; hRes = pConstraintList->AddFlushConstraint(pWPProxyA, pWPProxyB, varOffset, gkvarEmpty, gkvarEmpty, &pFlushConstraint); if (FAILED(hRes)) { ShowCOMError (hRes,L"AFCOTP AddFlushConstraint failed") ; return false ; }
if (kmmMax > 0.0) {
51Programming Inventor in C++
(C) 2021 Owen F Ransen
// This allows planes to be parallel constrained, but distant from each other const double kcmMax = kmmMax/10.0 ; CComPtr<ConstraintLimits> pLimits = pFlushConstraint->GetConstraintLimits() ; pLimits->MaximumEnabled = VARIANT_TRUE ; CString csMax ; csMax.Format (L"%.3f",kcmMax) ; CComBSTR TempBstr (csMax) ; pLimits->Maximum->Expression = TempBstr.m_str ; //!!!OWEN!!! .Value in cm is also possible }
if ((pszConstraintName != nullptr) && (wcslen(pszConstraintName) > 0)) { const CString kcsConsName = GetFreeConstraintName(pszConstraintName,pAsmCompDef); CComBSTR bstrName(kcsConsName); pFlushConstraint->put_Name(bstrName); }
return true ;}
Enter topic text here.
12.7 Change size of a hole
Here is an example:
void ChangeForoValvolinaDiam (CComPtr<PartComponentDefinition>&pPartCompDef, const double kmmNewDiam){ // Get the list of features... CComPtr<PartFeatures> pFeaturesList ; HRESULT hRes = pPartCompDef->get_Features(&pFeaturesList) ; if (FAILED(hRes)) { ShowCOMError(ekLogMsg,hRes,L"CFVD get_Features failed"); return ; }
// Find the feature which is the hole I want to change... CComPtr<PartFeature> pFeature; hRes = pFeaturesList->get_Item (CComVariant(L"ForoValvolina"), &pFeature); if (FAILED(hRes)) { ShowCOMError(ekLogMsg,hRes,L"CFVD get_Item failed"); return ; }
52 Autodesk Inventor Programming in C++ by Owen Ransen
(C) 2021 Owen F Ransen
// The name is correct, see if it is actually a hole... if (pFeature->GetType() == kHoleFeatureObject) {
// Convert the general pFeature it into the specificpHoleFeature // This is an example of using a CComQIPtr CComQIPtr<HoleFeature> pHoleFeature (pFeature) ; if (pHoleFeature == nullptr) { gLogger.Printf (ekLogMsg,L"Cannot cast") ; return ; }
// Get the value of the parameter as a variant... CComVariant cmDiam (pHoleFeature->HoleDiameter->GetValue()) ; const double kmmDiam = cmDiam.dblVal*10.0 ; gLogger.Printf (ekLogMsg,L"hole diam = %6.3fmm",kmmDiam);
// Change into centimeters... cmDiam.dblVal = kmmNewDiam/10.0 ;
// Actually change the size of the hole... pHoleFeature->HoleDiameter->Value = cmDiam ; }}
Enter topic text here.
12.8 Materials API
A part has "assets" which define the material of that part, assetsdescribe the material name, properties appearance etc.
You can use this code to examine the assets in a part document:
const long ikNumAssets = pPartDoc->Assets->GetCount(); for (long i = 0; i < ikNumAssets; i++) { CComPtr<Asset> pTempAsset = nullptr ; CComVariant iVar(i + 1); pPartDoc->Assets->get_Item(iVar,&pTempAsset); TRACE (L"%d material asset type %d has display name <%s> fixed name<%s> and category name <%s>", i+1, pTempAsset->AssetType, LPCWSTR(pTempAsset->DisplayName),
53Programming Inventor in C++
(C) 2021 Owen F Ransen
LPCWSTR(pTempAsset->Name), LPCWSTR(pTempAsset->GetCategoryName())); // e.g. "Copper" }
And the output will look something like this:
1 material asset type 99073 has display name <Copper - Satin>fixed name <Metal-022> and category name <Metal>2 material asset type 99073 has display name <Default> fixed name<InvGen-071> and category name <Miscellaneous>
The asset type will be one of these:
kAssetTypeAppearance99073
kAssetTypeMaterial99074
kAssetTypePhysicalProperties99075
kAssetTypeUnknown99076
If you look at the code at the start of this page you'll see that there isName and DisplayName. DisplayName will change with the languageversion of Inventor, but Name stays the same. Here are threeexamples:
Name: "Material-071" DisplayName(Italian): "Ferro, Duttile" DisplayName(English): "Iron, Ductile"Name: "Material-087" DisplayName(Italian): "Acciaio inox AISI 304" DisplayName(English): "Stainless Steel AISI 304"Name: "MaterialInv_024" DisplayName(Italian): "Acciaio inossidabile" DisplayName(English): "Stainless Steel"
In your program you'll generally have access to one DisplayName inthe language of the Inventor you are using, so you should considerusing Name. Name will not change from language to language.
I'm still investigating this, but it looks like the material is defined insidean Asset. Try this:
CComPtr<Asset> pAsset = nullptr ; pPartDoc->get_ActiveMaterial(&pAsset);
54 Autodesk Inventor Programming in C++ by Owen Ransen
(C) 2021 Owen F Ransen
TRACE (L"Active material asset has name <%s>", LPCWSTR(pAsset->DisplayName)); // e.g. "Copper"
TRACE (L"Active material asset has category name <%s>", LPCWSTR(pAsset->GetCategoryName())); // e.g. "Metal"
You can also get hold of the asset type, which will be one of these:
kAssetTypeAppearance 99073
kAssetTypeMaterial 99074
kAssetTypePhysicalProperties 99075
kAssetTypeUnknown 99076
You can loop over all the asset libraries loaded into inventor like this:
CComPtr<AssetLibraries> pAssLibs ; HRESULT hRes = pInvApp->get_AssetLibraries (&pAssLibs) ; if (FAILED(hRes) || (pAssLibs == nullptr)) { ShowCOMError (hRes,L"Could not get asset libraries"); return ; }
long iNumAssLibs ; pAssLibs->get_Count(&iNumAssLibs) ; WalertBoxA ("There are %d asset libraries",iNumAssLibs) ;
for (long iLib = 1 ; iLib <= iNumAssLibs ; iLib++) { CComPtr<AssetLibrary> pAssLib ; pAssLibs->get_Item (CComVariant(iLib),&pAssLib) ;
CComBSTRbstrDisplayName,bstrFullFileName,bstrInternalName ; pAssLib->get_DisplayName (&bstrDisplayName) ; pAssLib->get_FullFileName (&bstrFullFileName) ; pAssLib->get_InternalName (&bstrInternalName) ;
TRACE (L"Lib %d has <%s>, <%s>, <%s>.\n",iLib,bstrDisplayName,bstrFullFileName,bstrInternalName); }
And you'll get a result something like this:
Lib 1 has <Autodesk Material Library>, <C:\Program Files (x86)\Common Files\AutodeskShared\Materials\2015\PhysicalMaterial.adsklib>, <AD121259-C03E-4A1D-92D8-59A22B4807AD>.
55Programming Inventor in C++
(C) 2021 Owen F Ransen
Lib 2 has <Autodesk Appearance Library>, <C:\Program Files (x86)\Common Files\AutodeskShared\Materials\2015\assetlibrary_base.adsklib>, <314DE259-5443-4621-BFBD-1730C6CC9AE9>.Lib 3 has <Favorites>, <C:\Users\Owen\AppData\Roaming\Autodesk\Inventor2015\FavoriteMaterials.adsklib>, <D07F930C-485A-4658-AD69-C91D17FEB99B>.Lib 4 has <Inventor Material Library>, <C:\Users\Public\Documents\Autodesk\Inventor2015\Design Data\Materials\InventorMaterialLibrary.adsklib>, <AFEFC330-5E61-4E24-814F-AE810148B79D>.
The internal name is a GUID it looks like.
Once you have an asset lib you can loop over its contents like this:
CComPtr<AssetsEnumerator> pAssEnum ; pAssLib->get_MaterialAssets (&pAssEnum) ;
const long ikNumAssets = pAssEnum->Count ;
for (long iAss = 1 ; iAss <= ikNumAssets ; iAss++) { CComPtr<Asset> pAsset ; pAssEnum->get_Item (CComVariant(iAss),&pAsset) ;
CComBSTR bstrDispName,bstrName,bstrCatName ; pAsset->get_DisplayName (&bstrDispName) ; pAsset->get_Name (&bstrName) ; pAsset->get_CategoryName (&bstrCatName) ; TRACE (L" DisplayName=<%s> Name=<%s> CatName=<%s>\n", bstrDispName,bstrName,bstrCatName) ; }
And the results will look something like this:
DisplayName=<GFRC> Name=<Material-010> CatName=<Concrete> DisplayName=<Gold> Name=<Material-068> CatName=<Metal> DisplayName=<Iron, Ductile> Name=<Material-071> CatName=<Metal> DisplayName=<Lead> Name=<Material-072> CatName=<Metal> DisplayName=<Silver> Name=<Material-076> CatName=<Metal> DisplayName=<Steel> Name=<Material-077> CatName=<Metal> DisplayName=<Steel, Galvanized> Name=<Material-079> CatName=<Metal>
Name does not change from language to language, display name will.Categories are clearly Metal, Concrete, Wood etc.
56 Autodesk Inventor Programming in C++ by Owen Ransen
(C) 2021 Owen F Ransen
Material Assets serve to group a physical asset and appearancetogether. Conceptually a material can be described by its physicalproperties (density, Poisson’s ratio, yield strength, etc.) and how itlooks or its appearance. A material property has some basicinformation that identifies it, (name, description, type, etc.), and itreferences a physical properties asset.
Where do materials exist?
The number of asset libraries changes when you have nothing open(1 for examples) to when you have an assembly open (4 forexample).
The idea behind Consistent Materials is that all Autodesk programsuse the same library of materials.
There are three primary types of assets; materials, physicalproperties, and appearances
57Programming Inventor in C++
(C) 2021 Owen F Ransen
12.9 Model and User parameters programatically
Inside a PartComponentDefinition is a Parameters list which containstwo other lists, the model parameters and the user parameters:
Here is an example of listing the ModelParameters programatically:
void ListModelParameters (CComPtr<PartComponentDefinition>&pPartCompDef){ // Parameters contains two lists, Model and User... CComPtr<Parameters> pParameters ; pPartCompDef->get_Parameters (&pParameters) ;
// Get the model parameters list... CComPtr<ModelParameters> pModelParameters ;
58 Autodesk Inventor Programming in C++ by Owen Ransen
(C) 2021 Owen F Ransen
pParameters->get_ModelParameters (&pModelParameters) ;
// Print them all out with their names... const UINT ikNumModelParams = pModelParameters->Count ; for (UINT i = 1 ; i <= ikNumModelParams ; i++) { CComPtr<ModelParameter> pModelParam ; pModelParameters->get_Item (CComVariant(i),&pModelParam);
CComBSTR bstrParamName; pModelParam->get_Name (&bstrParamName) ;
TRACE (L"The name of model parameter %d is %s\n",i,bstrParamName) ; }}
From the above example you can imagine how to list theUserParameters.
You can change the values of the parameters like this:
HRESULT ChangeDoubleModelParam (const double kNewVal, const wchar_t* constpszModelParamName, CComPtr<PartComponentDefinition>&pPartCompDef)/*Change the value of a double (i.e. floating point) parameter of apart.Remember to understand internal units before calling this!*/{ // Parameters contains two lists, Model and User... CComPtr<Parameters> pParameters ; pPartCompDef->get_Parameters (&pParameters) ;
// Get the model parameters list... CComPtr<ModelParameters> pModelParameters ; pParameters->get_ModelParameters (&pModelParameters) ;
CComPtr<ModelParameter> pModelParam ; HRESULT hRes = pModelParameters->get_Item (CComVariant(pszModelParamName),&pModelParam) ;
59Programming Inventor in C++
(C) 2021 Owen F Ransen
if (FAILED(hRes) || (pModelParam == nullptr)) { return ReturnAndShowCOMError (hRes,L"ChangeDoubleModelParam, get_Item failed") ; }
// Change the value of the parameter hRes = pModelParam->put_Value (CComVariant(kNewVal)) ; if (FAILED(hRes) || (pModelParam == nullptr)) { return ReturnAndShowCOMError (hRes,L"CUnitshangeDoubleModelParam, put_Value failed") ; }
TRACE (L"New Value=%.3f\n",pModelParam->Get_Value()) ;
return (S_OK) ;}
You will probably not see an immediate change in your model whenyou call the above function, it needs a call to Update to do that:
ChangeDoubleModelParam (999.0,L"d0",pPartCompDef) ; ChangeDoubleModelParam (100.0,L"d5",pPartCompDef) ; ChangeDoubleModelParam ( 5.1,L"d9",pPartCompDef) ; pPartDocument->Update () ; // like regen in AutoCAD
Having a separate Update means you can change many parameterswithout having Inventor (wasting time) doing an Update after everychange.
See also parameter types and Units and reading model and userparameters programatically.
12.10 FlipNormal failure
Occasionally FlipNormal fails. According to AutoDesk...
I checked the implementation of FlipNormal. We block flippig the normal for
- Grounded- Origin- Fixed
workplanes.
60 Autodesk Inventor Programming in C++ by Owen Ransen
(C) 2021 Owen F Ransen
Does this explain why you might see a failure there?
Thanks,
Gerald
Fixed workplanes may be a result of adaptive geometry.
12.11 Adaptive geometry
I don't know what it is used for, but you can recognise it like this:
61Programming Inventor in C++
(C) 2021 Owen F Ransen
12.12 Add a sketch to an assembly or part
You can use these two functions:
// Adds a sketch to one of the three standard workplanes in a partbool AddSketchToStdPartWorkplane (CComPtr<PlanarSketch>& pNewSketch, CComPtr<PartComponentDefinition>&pPartCompDef, const wchar_t* const pszNewSketchName, const UINT ikWorkPlaneNumber) // gikXIndex,gikYIndex, gikZIndex{
62 Autodesk Inventor Programming in C++ by Owen Ransen
(C) 2021 Owen F Ransen
if ((pszNewSketchName == nullptr) || (wcslen(pszNewSketchName) == 0)) { gLogger.Printf (ekErrMsg,L"ASTSPW, workplane name incorrect") ; return false; }
CComPtr<WorkPlane> pWorkPlane; bool bOk = GetStdWorkPlaneByIndex(pWorkPlane, ikWorkPlaneNumber,pPartCompDef); if (!bOk) { return false; }
// Get the list of sketches CComPtr<PlanarSketches> pSketchList ; HRESULT hRes = pPartCompDef->get_Sketches (&pSketchList); if (FAILED(hRes)) { ShowCOMError (hRes,L"ASTSPW, could not get planar sketches") ; return false; }
hRes = pSketchList->Add (_variant_t((IDispatch*)pWorkPlane),VARIANT_FALSE,&pNewSketch) ; if (FAILED(hRes)) { ShowCOMError (hRes,L"ASTSPW, could not get planar sketches") ; return false; }
pNewSketch->put_Name (CComBSTR (pszNewSketchName)) ;
return true;}
/*******************************************************************************************************/
bool AddSketchToStdAssemblyWorkplane(CComPtr<PlanarSketch>& pNewSketch, CComPtr<AssemblyComponentDefinition>&pAsmCompDef, const wchar_t* const pszNewSketchName, const UINT ikWorkPlaneNumber) //gikXIndex, gikYIndex, gikZIndex{ // Get the work plane from the list of work planes in the part... CComPtr<WorkPlane> pWorkPlane; HRESULT hRes =pAsmCompDef->WorkPlanes->get_Item(CComVariant(ikWorkPlaneNumber),&pWorkPlane); if (FAILED(hRes)) { ShowCOMError (hRes,L"ASTSAW but 'get' %d failed\n",ikWorkPlaneNumber); return false ; }
// Get the list of sketches
63Programming Inventor in C++
(C) 2021 Owen F Ransen
CComPtr<PlanarSketches> pSketchList ; hRes = pAsmCompDef->get_Sketches (&pSketchList); if (FAILED(hRes)) { ShowCOMError (hRes,L"ASTSAW, could not get planar sketches") ; return false; }
hRes = pSketchList->Add (_variant_t((IDispatch*)pWorkPlane),VARIANT_FALSE,&pNewSketch) ; if (FAILED(hRes)) { ShowCOMError (hRes,L"ASTSAW, could not get planar sketches") ; return false; }
pNewSketch->put_Name (CComBSTR (pszNewSketchName)) ;
return true;}
12.13 How to get the value of a user parameter
Here is some code to get the value of a user parameter in an Inventorpart:
double GetUserParameterValueByName (CComPtr<PartComponentDefinition>&pPartCompDef, const CString& kcsUserParamName){ // Parameters contains two lists, Model and User... CComPtr<Parameters> pParameters ; pPartCompDef->get_Parameters (&pParameters) ;
// Get the model parameters list... CComPtr<UserParameters> pUserParameters ; pParameters->get_UserParameters (&pUserParameters) ;
// Find the one we are looking for... const UINT ikNumUserParams = pUserParameters->Count ;
for (UINT i = 1 ; i <= ikNumUserParams ; i++) { CComPtr<UserParameter> pUserParam ; pUserParameters->get_Item (CComVariant(i),&pUserParam) ;
CComBSTR bstrParamName; pUserParam->get_Name (&bstrParamName) ;
if (kcsUserParamName.CompareNoCase(CString(bstrParamName)) == 0) { // Found it VARIANT ParamValue ;
64 Autodesk Inventor Programming in C++ by Owen Ransen
(C) 2021 Owen F Ransen
pUserParam->get_Value (&ParamValue) ; return ParamValue.dblVal; } }
// This is an error
return 0.0;}
And here is the very similar code for getting a model parameter value:
double GetModelParameterValueByName (CComPtr<PartComponentDefinition>&pPartCompDef, const CString& kcsModelParamName){ // Parameters contains two lists, Model and User... CComPtr<Parameters> pParameters ; pPartCompDef->get_Parameters (&pParameters) ;
// Get the model parameters list... CComPtr<ModelParameters> pModelParameters ; pParameters->get_ModelParameters (&pModelParameters) ;
// Find the one we are looking for... const UINT ikNumModelParams = pModelParameters->Count ; for (UINT i = 1 ; i <= ikNumModelParams ; i++) { CComPtr<ModelParameter> pModelParam ; pModelParameters->get_Item (CComVariant(i),&pModelParam) ;
CComBSTR bstrParamName; pModelParam->get_Name (&bstrParamName) ;
if (kcsModelParamName.CompareNoCase(CString(bstrParamName)) == 0) { // Found it VARIANT ParamValue ; pModelParam->get_Value (&ParamValue) ; return ParamValue.dblVal; } }
// This is an error
return 0.0;}
See also Model and User parameters programatically.
65Programming Inventor in C++
(C) 2021 Owen F Ransen
12.14 Getting the value of a custom iProperty
Here is a function which gets a custom iProperty value, returningfalse if the value does not exist in the document.
So it can be used to test for existence as well as getting the actualvalue.
// Returns true if the custom iProperty exists, with the value incsRetValue Needs a DOC not a PART or ASSEMBLY// Always returns a string in csRetValueboolean DocHasCustomiProperty(CComPtr<Document>& pInventorDoc,const CString& kcsiPropName, CString& csRetValue) { csRetValue = CString ("") ;
CComPtr <PropertySets> pPropSets; pInventorDoc->get_PropertySets(&pPropSets);
const long ikNumSets = pPropSets->Count;
// There are several sets of properties, loop over thesets... for (long iSet = 1; iSet <= ikNumSets; iSet++) { CComPtr<PropertySet> pPropSet; pPropSets->get_Item(CComVariant(iSet), &pPropSet);
CComBSTR bstrPropSetName; pPropSet->get_Name(&bstrPropSetName); CString csPropSetName(bstrPropSetName);
if (csPropSetName.CompareNoCase(L"Inventor User DefinedProperties") == 0) { // Loop over the properties of this property set... const long ikNumProps = pPropSet->Count;
for (long iProp = 1; iProp <= ikNumProps; iProp++) { CComPtr<Property> pThisProp; pPropSet->get_Item(CComVariant(iProp), &pThisProp);
_bstr_t bstrPropName = pThisProp->GetDisplayName();
const CString
66 Autodesk Inventor Programming in C++ by Owen Ransen
(C) 2021 Owen F Ransen
kcsThisPropName(bstrPropName.GetBSTR());
if (kcsThisPropName.CompareNoCase(kcsiPropName)== 0) { // We've found the property we are interestedin... // ...convert it into a string CComVariant varValue; pThisProp->get_Value(&varValue);
// Add more VT_... values for more detail... if (varValue.vt == VT_BSTR) { csRetValue = CString(varValue.bstrVal);
} else if (varValue.vt == VT_I4) { csRetValue.Format(L"%d",varValue.intVal);
} else if (varValue.vt == VT_R8) { csRetValue.Format(L"%.3f",varValue.dblVal);
} else { csRetValue.Format(L"(?vt=%d?)",varValue.vt); }
return true; } } } }
return false ;}
12.15 Add a part to an assembly
...or more properly how to add an occurrence of a part to anassembly. Here you go, and you specify the 3d position and optionallythe 3d angles too...
HRESULT AddPartToAssemblyAtPosition (CComPtr<AssemblyComponentDefinition>& pAsmCompDef, const CString& kcsFullPathPartName, const double kxPos,
67Programming Inventor in C++
(C) 2021 Owen F Ransen
const double kyPos, const double kzPos, CComPtr<ComponentOccurrence>& pPartOcc, CComQIPtr<PartComponentDefinition>& pPartCompDef, const double kxRotDegs /*=0.0*/, const double kyRotDegs /*=0.0*/, const double kzRotDegs /*=0.0*/) /*The positions are in the natural units of Inventor, usually cmWe return the occurence and its part component definition*/{ pPartOcc = nullptr ;
CComPtr<ComponentOccurrences> pOccurrencesList = nullptr; HRESULT hRes = pAsmCompDef->get_Occurrences (&pOccurrencesList) ; if (FAILED(hRes)) { return ReturnAndShowCOMError (hRes,L"AddPartToAssemblyAtPosition get_Occurrences failed") ; }
CComPtr<TransientGeometry> pTransGeom = GetTransGeomPtr () ; CComPtr<Matrix> pPosMatrix; pTransGeom->CreateMatrix(&pPosMatrix);
CComPtr<Vector> pVector; // Create a Vector to modify the Matrix pTransGeom->CreateVector(kxPos,kyPos,kzPos,&pVector);
// Make the matrix a "move to point" matrix... pPosMatrix->SetTranslation (pVector,VARIANT_TRUE) ;
CComPtr<Matrix> pPosRotMatrix ; pTransGeom->CreateMatrix(&pPosRotMatrix);
CComPtr<Vector> pZAxis ; hRes = pTransGeom->CreateVector (0,0,1,&pZAxis); if (FAILED(hRes)) { ShowCOMError (hRes,L"Could not create z axis vector") ; return false ; }
CComPtr<Point> pOrigin ; hRes = pTransGeom->CreatePoint (0,0,0,&pOrigin); const double kZRadsRot = RadsFromDegs(kzRotDegs); pPosRotMatrix->SetToRotation (kZRadsRot,pZAxis,pOrigin) ;
pPosRotMatrix->PreMultiplyBy(pPosMatrix);
hRes = pOccurrencesList->Add (CComBSTR(kcsFullPathPartName),pPosRotMatrix,&pPartOcc) ; if (FAILED(hRes)) {
68 Autodesk Inventor Programming in C++ by Owen Ransen
(C) 2021 Owen F Ransen
return ReturnAndShowCOMError (hRes,L"AddPartToAssemblyAtPosition Add failed") ; }
// Get the general component definition... CComQIPtr<ComponentDefinition> pCompDef ; hRes = pPartOcc->get_Definition (&pCompDef) ; if (FAILED(hRes)) { return ReturnAndShowCOMError (hRes,L"AddPartToAssemblyAtPosition could not get definition.") ; }
// Cast from the general sort of component definition to the specific PART component definition pPartCompDef = CComQIPtr<PartComponentDefinition>(pCompDef); if (pPartCompDef == nullptr) { gLogger.Printf (ekErrMsg,L"AddPartToAssemblyAtPosition could not cast to pPartCompDef.") ; return E_FAIL ; }
return S_OK ;}
12.16 Open an assembly part programatically
Here's a function to do it:
bool OpenAssembly (CComPtr<AssemblyComponentDefinition>& pAsmCompDef, //Output CComPtr<AssemblyDocument>& pAsmDoc, // Output const CString& kcsFullAsmFileName, // Input const bool kbOpenVisible/*=true*/) // Input{ CComBSTR strAssemblyFilename (kcsFullAsmFileName) ;
// Get the list of documents, we use this to oprn another CComPtr<Documents> pDocuments; HRESULT hRes = theApp.GetInvAppPtr()->get_Documents (&pDocuments) ; if (FAILED(hRes)) { ShowCOMError(hRes, L"get_Documents called from OpenAssembly"); return false; }
VARIANT_BOOL vbOpenVisible; if (kbOpenVisible) { vbOpenVisible = VARIANT_TRUE; } else { vbOpenVisible = VARIANT_FALSE; }
CComPtr<Document> pDoc = nullptr ;
69Programming Inventor in C++
(C) 2021 Owen F Ransen
hRes = pDocuments->Open (strAssemblyFilename, // what to open vbOpenVisible, &pDoc) ; if (FAILED(hRes)) { ShowCOMError (hRes,L"OA, could not open assembly, pDocuments->Open(%s)",kcsFullAsmFileName); return false ; }
// Try to cast from a general doc to an assembly pAsmDoc = pDoc; if (pAsmDoc == nullptr) { ShowCOMError (hRes,L"OA, failed to cast to AssemblyDocument"); return false ; }
hRes = pAsmDoc->get_ComponentDefinition(&pAsmCompDef); if (FAILED(hRes)) { ShowCOMError (hRes,L"OA, could not open assembly %s",kcsFullAsmFileName); return false ; }
return true;}
Note the kbOpenVisible. Another example of invisible opening:
CComPtr<Document> pDoc ;hRes = pDocuments->Open (strAssemblyFilename, // what to open VARIANT_FALSE, // open it invisible &pDoc) ; // result
Note that if you just want to interrogate the data of a part or assemblyopening it invisibly will be faster.
If you don't like that function...:
CComBSTR strAssemblyFilename ; strAssemblyFilename = L"C:\\George\\Best.iam" ;
CComPtr<Document> pDoc ; hRes = pDocuments->Open (strAssemblyFilename,VARIANT_TRUE,&pDoc) ; if (FAILED(hRes) || (pDoc == nullptr)) { ShowCOMError (hRes,L"OpenAssembly, Open failed "); return ; }
70 Autodesk Inventor Programming in C++ by Owen Ransen
(C) 2021 Owen F Ransen
// Try to cast from a general doc to an assembly CComQIPtr<AssemblyDocument> pAsmDoc (pDoc); if (pAsmDoc == nullptr) { ShowCOMError (hRes,L"Failed to cast to AssemblyDocument"); return ; }
// Now you can use pAsmDoc, the assembly document // ...
12.17 Landscape and Portrait orientation getting and setting
Programatically you can get and set the orientation of a drawingdocument like this:
CComPtr<Sheet> pSheet ; ... ... ...
PageOrientationTypeEnum Orientation; pSheet->get_Orientation(&Orientation);
pSheet->put_Orientation(kPortraitPageOrientation);
/* these are the other enum values: kDefaultPageOrientation kLandscapePageOrientation*/
The coordinate system within a sheet does not change, 0,0 bottomleft. See also adding a sheet to a drawing.
71Programming Inventor in C++
(C) 2021 Owen F Ransen
12.18 Adding a sheet to a drawing
Here is a graphical overview of Drawings Sheets and Views:
Note that when you first create a drawing you already have a singlesheet, so often there is no need to add another one.
Anyway, to add a Sheet to a drawing you must get hold of thedrawing object's Sheets list and call the Add method. Here is a
72 Autodesk Inventor Programming in C++ by Owen Ransen
(C) 2021 Owen F Ransen
fragment, error checking removed:
CComQIPtr<DrawingDocument> pDrawingDoc ; pDrawingDoc = ...
CComPtr<Sheets> pSheets = nullptr ; pDrawingDoc->get_Sheets(&pSheets) ;
CComVariant varReal (0.0) ; CComPtr<Sheet> pSheet = nullptr ; pSheets->Add (kA3DrawingSheetSize, kDefaultPageOrientation, L"View77", varReal, // width (not used in this case) varReal, // height (not used in this case) &pSheet) ;
The DrawingSheetSizeEnum Enumerator (first parameter in theabove call to Add) has many options, here a just a few:
kA3DrawingSheetSize 9996 A3 size (typically for metric units). kA4DrawingSheetSize 9997 A4 size (typically for metric units).kADrawingSheetSize 9987 A size (typically for inch units). kBDrawingSheetSize 9988 B size (typically for inch units).kCDrawingSheetSize 9989 C size (typically for inch units).kCustomDrawingSheetSize 9986 Custom size. Does (may) not fit one of the standard sizes.
If you use kCustomDrawingSheetSize then Width and Height must bespecified.
The orientation of the sheet (second parameter in the above call toAdd) will be one of these:
kDefaultPageOrientation 10241 Specifies the default setting. kLandscapePageOrientation 10242 Page is oriented as a Landscape.kPortraitPageOrientation 10243 Page is oriented as a Portrait.
You'll see the two drawings in a single sheet in the browser like this:
73Programming Inventor in C++
(C) 2021 Owen F Ransen
See also Landscape and Portrait orientation.
12.19 Compile/Link Errors and how to correct them
12.19.1 _WIN32_WINNT error
If you get this error:
"This file requires _WIN32_WINNT to be #defined at least to 0x0403.Value 0x0501 or higher is recommended."
You need to add this to your preprocessor defines:
_WIN32_WINNT=0x0501
in the preprocessor compilation tab of your Inventor project.
74 Autodesk Inventor Programming in C++ by Owen Ransen
(C) 2021 Owen F Ransen
12.19.2 error MSB3075: The command regsvr32 /s /c...
With registry free AddIns you probably don't need to know this anymore, but just in case:
regsvr32 needs admin rights to operate. It is called from within VisualStudio. So you must run Visual Studio "as the administrator" if youare creating old style plugins for Inventor.
It is not sufficient to be the administrator, you need to run as...
12.19.3 Error MK_E_UNAVAILABLE 0x800401e3
This has something to do with the ROT (Running Object Table) nothaving Inventor in it (yet).
Sometimes even though you have a running Inventor this code:
hRes = ::GetActiveObject (InvAppClsid, NULL, &pInvAppUnk); if (FAILED (hRes)) {
will fail with the error 0x800401e3
I've not been able to understand the underlying problem yet. But onething to check is that both processes are running at the same level,both non admin for example.
But see this as well.
This could be that you are running the compiler as administrator andInventor as normal user.
75Programming Inventor in C++
(C) 2021 Owen F Ransen
12.19.4 Include file paths
Here are two include paths you will have to add to get your projects compile:
C:\Users\Public\Documents\Autodesk\Inventor 2017\SDK\DeveloperTools\IncludeC:\Program Files\Autodesk\Inventor 2017\Bin\Bin32
Else you'll get a C1083 "cannot open include file" problem. Of courseyou may be using a different version of Inventor and the patha onyour computer may be slightly different.
InventorUtils.h is usually placed in the stdafx.h file for your project.You add the paths in the dialog shown below. (The string is very lngso the dialog does not show it, but basically you tack the twodirectories above onto the end of whatever is already there in theInclude Directories edit box, separated by semicolons.)
For 2015:
76 Autodesk Inventor Programming in C++ by Owen Ransen
(C) 2021 Owen F Ransen
12.19.5 CLSIDFromProgID error resolution
You have this usually:
CLSID InvAppClsid; HRESULT hRes = CLSIDFromProgID (L"Inventor.Application",&InvAppClsid); if (FAILED(hRes)) { pInvApp = nullptr ; return ReturnAndShowCOMError (hRes,L"ConnectToInventor,CLSIDFromProgID failed") ; }
Which may fail with this error:
ConnectToInventor, CLSIDFromProgID failedError = 800401f3WCode = 0000Meaning = Stringa dell'interfaccia non valida.
This could be that you are running the compiler as administrator andInventor as normal user.
77Programming Inventor in C++
(C) 2021 Owen F Ransen
12.19.6 C2064: term does not evaluate to a function taking 0 arguments
If you get this error:
1>c:\...\sources\book\testfunctions.cpp(51): error C2064: term does not evaluate to afunction taking 0 arguments
...it could well be that you are calling, for example, a member variableas if it is a function:
VARIANT_BOOL bIs = piPartCompDef->IsiPartFactory () ;
In other words you have used brackets () where they are not required.You should write this:
VARIANT_BOOL bIs = piPartCompDef->IsiPartFactory ;
Another example would be the oft used Count. The following is anerror because Count is not a function:
long iNumAssets = pAssEnum->Count() ;
Count is a member variable, this is the correct way of accessing it:
long iNumAssets = pAssEnum->Count ;
12.19.7 C2774 compile error
You'll get this if you try to modify a property which cannot be modified.For example:
pPartDoc->FullDocumentName = L"Whatever" ;
FullDocumentName of a Part cannot be changed.
78 Autodesk Inventor Programming in C++ by Owen Ransen
(C) 2021 Owen F Ransen
12.19.8 Failed to register
When you installl the Inventor addin making wizard for Visual Studioyou may well get this message:
In fact it may well have worked, click on Continue then go into VisualStudio to see if the Inventor plugin AddIn project wizard is there.
12.19.9 Four API methods warning when compiling for MFC
Yes, those four API methods have the same name with the methodswhich are introduced by Windows library. The clients need to userename to remove the warning.
And about the question that the client asks whether could change themethods name in Inventor type library, I am afraid not, because wehave rules that once a library is released to customer, we don't allowto update the method names, unless there is a special requirement,such as the method parameters needs be updated based on designor the method is totally useless. And about the four methods"DeleteFile", "CopyFile", "MoveFile" and "SetEnvironmentVariable",they are all old methods which exist for many Inventor releases. So Ithink they will not be renamed unless PD's permission.
These have existed since almost the beginning of the Inventor API. Ideally we would not have the name conflict but this isn't a big issueand we do not see it hasn't caused any big problems for the pastmany years.
79Programming Inventor in C++
(C) 2021 Owen F Ransen
12.20 Open an Inventor part programatically
This function opens an Inventor part, and returns the PartDocumentand the PartComponentDefinition, both of which are usually useful tothe caller.
HRESULT OpenPart (CComPtr<PartComponentDefinition>&pPartCompDef, // output CComPtr<PartDocument>& pPartDoc, // output const CString& csFullPartFileName, // input CComPtr<Application>& pInvApp) // input/*Opens a part in a separate Inventor document*/{ // Read in the correct file. CComPtr<Documents> pDocs = nullptr ; HRESULT hRes = pInvApp->get_Documents (&pDocs) ; if (FAILED(hRes) || (pDocs == nullptr)) { return ReturnAndShowCOMError (hRes,L"OpenPart,get_Documents failed "); }
CComPtr<Document> pDoc = nullptr ; hRes = pDocs->Open (CComBSTR(csFullPartFileName),VARIANT_TRUE,&pDoc) ; if (FAILED(hRes) || (pDoc == nullptr)) { return ReturnAndShowCOMError (hRes,L"OpenPart, Openfailed "); }
pPartDoc = pDoc ; if (pPartDoc == nullptr) { return ReturnAndShowCOMError (hRes,L"OpenPart, failed tocast to PartDocument"); }
// Get assembly component definition
80 Autodesk Inventor Programming in C++ by Owen Ransen
(C) 2021 Owen F Ransen
pPartCompDef = nullptr ; hRes = pPartDoc->get_ComponentDefinition(&pPartCompDef) ; if (FAILED(hRes) || (pPartCompDef == nullptr)){ return ReturnAndShowCOMError (hRes,L"OpenPartget_ComponentDefinition failed "); }
return (S_OK) ;}
12.21 PutFullFileName exception
It seems to me that if you do a PutFullFileName on an assembly thathas already been saved you'll get an exception.
This is because once set FullFileName cannot be altered after asave.
"The FullFileName property can only be set on a file if the file hasnever been saved. If a file has been saved, the FullFileName propertybecomes read-only. In order to perform the copy operation that youare talking about, you will need to do a file copy (using FileManager.CopyFile or Document.SaveAs), followed by FileDescriptor.ReplaceReference in order to fix up the references on the copiedfile.."
12.22 MessageBox vs MsgBox
MessageBox is an object used in iLogic:
MessageBox.Show ("Assembly " & invDocument.FullFileName & " has " & DocsInAsm.Count & " sub documents")
MsgBox is a function used in VBA.
MsgBox ("Questa funziona solo con disegni IDW")
81Programming Inventor in C++
(C) 2021 Owen F Ransen
12.23 InternalName vs DisplayName
Here's an example of an internal name and an external name of apart:
InternalName: {28494CA8-42AD-0898-8E49-DA9EB61E9E3F}DisplayName: 1234IRON.ipt
The InternalName is probably never any use to you, an add onprogrammer.
12.24 Add a circle to a sketch function
Here's a function for adding a circle to a sketch:
HRESULT AddCircleToSketch (CComPtr<PlanarSketch>& pSketch, const double xCenter, const double yCenter, const double kDiam, CComPtr<Application>& pInvApp) { CComPtr<TransientGeometry> pTransGeom ; GetTransGeomPtr (pTransGeom,pInvApp) ;
CComPtr<Point2d> pCenter; pTransGeom->CreatePoint2d(xCenter,yCenter,&pCenter);
HRESULT hRes =pSketch->SketchCircles->AddByCenterRadius(pCenter,kDiam/2.0); if (FAILED(hRes)) { return ReturnAndShowCOMError (hRes,L"AddCircleToSketchbut could not add by radius (Outer)\n"); }
return (S_OK) ;}
Note that this function uses the transient geometry object.
If you don't need that circle itself you can just ignore that lastparameter, like this:
82 Autodesk Inventor Programming in C++ by Owen Ransen
(C) 2021 Owen F Ransen
hRes =pSketch->SketchCircles->AddByCenterRadius(pCenter,kDiam/2.0);
...because it defaults to 0.
12.25 Standard WorkPlane getting
In this function gikXIndex means the plane at X=0, which is of coursethe YZ Plane. And so on.
HRESULT GetStdWorkPlaneByIndex (CComPtr<WorkPlane>& pWorkPlane, const UINT ikIndex, // gikXIndex, gikYIndex, gikZIndex CComPtr<PartComponentDefinition>& pPartCompDef) { if ((ikIndex < gikXIndex) || (ikIndex > gikZIndex)) { TRACE (L"GWPBI index out of range: %d\n",gikXIndex) ; return E_FAIL ; }
// Get the work plane from the list of work planes in the part... HRESULT hRes = pPartCompDef->WorkPlanes->get_Item(CComVariant(ikIndex), &pWorkPlane); if (FAILED(hRes) || (pWorkPlane == nullptr)) { ShowCOMError (hRes,L"GWPBI but 'get' %d failed\n",ikIndex); return E_FAIL ; }
return S_OK ;}
Here is how to use the function:
hRes = GetStdWorkPlaneByIndex (pFlangiaPlane, gikYIndex, // the plane at Y=0, XZ pFlangiaCompDef) ;
83Programming Inventor in C++
(C) 2021 Owen F Ransen
12.26 Creating folders in the browser programatically
Sometimes it is useful to have browser pane folders to hide detail.Here is how to create a folder programatically. You will need thename of the folder and an object collection of the occurrences to putinside the folder:
// Create a new folder so grouping together the object occurrences inpObjCollectionbool CreateNewPaneFolder (const CString& kcsFolderName, CComPtr<ObjectCollection>& pObjCollection){ CComPtr<Document> pActiveDoc; HRESULT hRes = theApp.GetInvAppPtr()->get_ActiveDocument(&pActiveDoc); if (FAILED(hRes)) { TRACE L"CNFP get_ActiveDocument failed"); return false; }
CComPtr<BrowserPanes> pPanes = nullptr; hRes = pActiveDoc->get_BrowserPanes (&pPanes) ; if (FAILED(hRes)) { TRACE (L"CNFP get_BrowserPanes failed"); return false; }
BrowserPaneObjectPtr pCctPane; hRes = pPanes->get_ActivePane (&pCctPane) ; if (FAILED(hRes)) { TRACE (L"CNPF get_ActivePane failed"); return false; }
// Do this so you can create object collection... CComPtr<TransientObjects> pTransObjs = GetTransientObjectsPtr() ;
CComPtr<ObjectCollection> pNodeCollection = nullptr ; hRes = pTransObjs->CreateObjectCollection (gkvarEmpty,&pNodeCollection) ; if (FAILED(hRes)) { TRACE (L"CNPF CreateObjectCollection for workaxes failed.") ; return false ; }
for (long i = 1; i <= pObjCollection->Count; i++) { CComPtr<BrowserNode> pThisBrowserNode; pCctPane->GetBrowserNodeFromObject(pObjCollection->GetItem(i),&pThisBrowserNode); pNodeCollection->Add(pThisBrowserNode); }
CComVariant cvNodeColl(pNodeCollection); CComBSTR bstrFolderName(kcsFolderName);
84 Autodesk Inventor Programming in C++ by Owen Ransen
(C) 2021 Owen F Ransen
hRes = pCctPane->AddBrowserFolder(bstrFolderName, cvNodeColl); if (FAILED(hRes)) { TRACE (L"CNPF AddBrowserFolder failed"); return false ; }
return true;}
Note that AddBrowserFolder will create a new folder, even if a folderof the same name already exists.
12.27 Getting the names of browser folders
Here is how to loop over browser folders and print out the name ofeach folder:
// Get the root of the pane of browser folders CComPtr<BrowserNode> pTopNode; pCctPane->get_TopNode(&pTopNode);
// Get the enumerator to loop over the browser folders... BrowserFoldersEnumeratorPtr SubFolders = pTopNode->GetBrowserFolders();
gLogger.Printf(ekLogMsg, L"Create new pane folder, %d already exist\n",SubFolders->Count);
// Loop over the browser folders... for (int f = 1; f <= SubFolders->Count; f++) {
// Get the folder... BrowserFolderPtr BrowserPtr = SubFolders->GetItem(f);
// Get its name and print it... CComBSTR cStr; BrowserPtr->get_Name(&cStr); CString csName(cStr); gLogger.Printf(ekLogMsg, L"Folder %03d is <%s>", f, csName); }
Enter topic text here.
85Programming Inventor in C++
(C) 2021 Owen F Ransen
12.28 How to set the BOM Reference property in a part occurrence
The reference property prevents the part occurring in a BOM or partslist.
CComPtr<ComponentOccurrence> pCctNodesOcc; CComQIPtr<PartComponentDefinition> pCctNodesDef ; hRes = AddPartToAssemblyAtPosition (pAssemblyCompDef, kcsNodesPartFullName, 0.0,0.0,0.0, // x y z position pCctNodesOcc, // return value pCctNodesDef) ; // return value if (FAILED(hRes)) { gLogger.Printf (ekErrMsg,"Bulb7 failed") ; return ; }
// This makes the occurrence a Reference which means it does not appear inthe Parts Only parts list pCctNodesOcc->put_Reference(VARIANT_TRUE);
12.29 Listing the contents of a model view BOM
Once you have an assembly comp def you need to get hold of theBOM and then the BOM views. There are usually three, you need tolook for the model view. Then you can list the contents:
// Find the BOM of this assembly CComPtr<BOM> pBOM; HRESULT hRes = pAsmCompDef->get_BOM(&pBOM); if (FAILED(hRes) || (pBOM == nullptr)) { ShowCOMError(hRes,L"ALUICBOM, Could not get BOM"); return ; }
// There are usually three types of view CComPtr<BOMViews> pBOMViews; hRes = pBOM->get_BOMViews(&pBOMViews); if (FAILED(hRes) || (pBOMViews == nullptr)) { ShowCOMError(hRes,L"ALUICBOM, Could not get BOMViews"); return ; }
long iNumBomViews; pBOMViews->get_Count(&iNumBomViews);
for (long bv = 1; bv <= iNumBomViews; bv++) { CComVariant varNum(bv); CComPtr<BOMView> pBomView; pBOMViews->get_Item(varNum, &pBomView);
86 Autodesk Inventor Programming in C++ by Owen Ransen
(C) 2021 Owen F Ransen
BOMViewTypeEnum eBVTYpe; pBomView->get_ViewType(&eBVTYpe);
if (eBVTYpe != kModelDataBOMViewType) { continue; // I'm only interested in the first tab, the model BOM }
gLogger.Printf(ekLogMsg, L"BOM Type %d == kModelDataBOMViewType",eBVTYpe);
CComPtr<BOMRowsEnumerator> BomRows; pBomView->get_BOMRows(&BomRows);
// Look at each row in the bom for (long iRow = 1; iRow <= BomRows->Count; iRow++) { CComPtr<BOMRow> ThisBomRow; BomRows->get_Item(iRow, &ThisBomRow);
// Of this row, what is the component? Usually there is onlyone... CComPtr<ComponentDefinitionsEnumerator> pDefinitionsEnum; ThisBomRow->get_ComponentDefinitions(&pDefinitionsEnum);
// ...assuming there is only one I get the first CComPtr<ComponentDefinition> pCompDef; pDefinitionsEnum->get_Item(1, &pCompDef) ;
// Get the definition of the part listed in this BOM row CComPtr<PartComponentDefinition> pPartCompDef; pPartCompDef = pCompDef; if (pPartCompDef == nullptr) { continue; }
CString csPartName = GetPartName(pPartCompDef);
... etc etc... } }
You may find this function useful:
// Returns the BOM view in pBomView and true if all went wellbool GetModelDataBOMView(CComPtr<BOMView>& pBomView, // return value CComPtr<AssemblyComponentDefinition>& pAsmCompDef){ // Find the BOM of this assembly CComPtr<BOM> pBOM; HRESULT hRes = pAsmCompDef->get_BOM(&pBOM); if (FAILED(hRes) || (pBOM == nullptr)) { ShowCOMError(hRes,L"GMDBOMV, Could not get BOM"); return false ; }
87Programming Inventor in C++
(C) 2021 Owen F Ransen
// There are usually three types of view CComPtr<BOMViews> pBOMViews; hRes = pBOM->get_BOMViews(&pBOMViews); if (FAILED(hRes) || (pBOMViews == nullptr)) { ShowCOMError(hRes,L"GMDBOMV, Could not get BOMViews"); return false ; }
long iNumBomViews; pBOMViews->get_Count(&iNumBomViews);
gLogger.Printf(ekLogMsg, "There are %d BOM views", iNumBomViews);
for (long bv = 1; bv <= iNumBomViews; bv++) { CComVariant varNum(bv); pBOMViews->get_Item(varNum, &pBomView);
BOMViewTypeEnum eBVTYpe; pBomView->get_ViewType(&eBVTYpe);
if (eBVTYpe == kModelDataBOMViewType) { return true ; // Done! Finished! Found! } }
return false;
}/**********************************************************************************************/
12.30 Static quantity in a BOM
Sometimes you want to force the number in a static quantity in aBOM. Here's an example of how you can do this, as long as the partyou have inserted as the appropriate BOM unit.
void PutStaticQuantity(CComPtr<BOMRow>& pBomRow, const int ikUse){ CString csQuantity;
csQuantity.Format(L"%d",ikUse);
CComBSTR bstrNewTotalQuantity = csQuantity ;
// Do this *before* you do put_TotalQuantityOverridden HRESULT hRes = pBomRow->put_TotalQuantity(bstrNewTotalQuantity);
88 Autodesk Inventor Programming in C++ by Owen Ransen
(C) 2021 Owen F Ransen
// Do this after *put_TotalQuantity* is called hRes = pBomRow->put_TotalQuantityOverridden(VARIANT_TRUE);}
12.31 Documents referenced by a 2d view in an IDW
A (2D) drawing view obviously referenced documents (3D assembliesand 3D parts), how do you get hold of the referenced documents.Here a code fragment to help you do it:
CComPtr<DrawingView> pThisView = nullptr ; ... // What main document does this view look at? (Here I assume it is anassembly) CComPtr<DocumentDescriptor> pDocDesc = nullptr; pThisView->get_ReferencedDocumentDescriptor(&pDocDesc); CComQIPtr<AssemblyDocument>pDoc = pDocDesc->ReferencedDocument;
// Get the definition of the referenced assembly.... CComPtr<AssemblyComponentDefinition> pAsmCompDef = nullptr; pDoc->get_ComponentDefinition(&pAsmCompDef);
// Get the list of components (usually parts) in the assemly... CComPtr<ComponentOccurrences> pOccList = nullptr; pAsmCompDef->get_Occurrences(&pOccList);
CComQIPtr<PartComponentDefinition> pPartDef = nullptr; CComPtr<PartDocument> pOccDoc = nullptr;
// Loop over all the parts writing out the name of the part... for (long o = 1; o <= pOccList->Count; o++) { CComPtr<ComponentOccurrence> pOcc = nullptr; pOccList->get_Item(o, &pOcc);
CComPtr<ComponentDefinition> pDef = nullptr ; pOcc->get_Definition(&pDef); pPartDef = pDef ; pPartDef->get_Document((IDispatch**)&pOccDoc);
const CString kcsOccFullFileName(BSTR(pOccDoc->FullFileName));
pOccDoc = nullptr;
TRACE L"Found part doc <%s>", kcsOccFullFileName); }
89Programming Inventor in C++
(C) 2021 Owen F Ransen
12.32 Add a DrawingSketch to a DrawingDocument
Here's a function for doing that:
// Add a sketch with the given name to the DrawingDocumentbool AddSketchToIDW(CComPtr<DrawingSketch>& pDrawingSketch, // return value CComQIPtr<DrawingDocument>& pDrawingDoc, // In which docto add the sketch const CString& kcsNewSketch) // Name of the new sketch{ // Find the sheets of the drawing document... CComPtr<Sheets> pSheets = nullptr ; HRESULT hRes = pDrawingDoc->get_Sheets(&pSheets) ; if (FAILED(hRes)) { ShowCOMError (hRes,L"ASTI, could not get sheets of drawing document."); return false ; }
// Get the (assumed) single sheet inside the IDW. Remember the firstobject // in a COM list has index 1... CComPtr<Sheet> pSheet = nullptr ; hRes = pSheets->get_Item (CComVariant(1),&pSheet) ; if (FAILED(hRes)) { ShowCOMError (hRes,L"ASTI, could not get 1st sheet of drawing."); return false ; }
// Get hold of the list of drawing sketches of this sheet... CComPtr<DrawingSketches> pSketches = nullptr ; hRes = pSheet->get_Sketches(&pSketches); if (FAILED(hRes)) { ShowCOMError (hRes,L"ASTI, could not get drawing sketches."); return false ; }
// Add a new drawing sketch // CComPtr<DrawingSketch> pDrawingSketch ; hRes = pSketches->Add(&pDrawingSketch); if (FAILED(hRes)) { ShowCOMError (hRes,L"ASTI, could not aad sketch."); return false ; }
pDrawingSketch->put_Name(CComBSTR(kcsNewSketch));
return true ;}
90 Autodesk Inventor Programming in C++ by Owen Ransen
(C) 2021 Owen F Ransen
Here's an example of adding lines and text to a drawing sketch..
12.33 Adding lines text and circles to a DrawingSketch
A DrawingSketch is a 2D sketch created on an Inventor drawing, anIDW. Here is an example which creates a DrawingSketch and thenadds some radial lines and some text to it:
// Find the sheets of the drawing document... CComPtr<Sheets> pSheets = nullptr ; HRESULT hRes = pDrawingDoc->get_Sheets(&pSheets) ; if (FAILED(hRes)) { ShowCOMError (hRes,L"ASTI, could not get sheets of drawing document."); return ; }
// Get the (assumed) single sheet inside the IDW. Remember the firstobject // in a COM list had index 1... CComPtr<Sheet> pSheet = nullptr ; hRes = pSheets->get_Item (CComVariant(1),&pSheet) ; if (FAILED(hRes)) { ShowCOMError (hRes,L"ASTI, could not get 1st sheet of drawing."); return ; }
CComPtr<DrawingSketches> pSketches ; hRes = pSheet->get_Sketches(&pSketches); if (FAILED(hRes)) { ShowCOMError (hRes,L"ASTI, could not get drawing sketches."); return ; }
CComPtr<DrawingSketch> pDrawingSketch ; hRes = pSketches->Add(&pDrawingSketch); if (FAILED(hRes)) { ShowCOMError (hRes,L"ASTI, could not aad sketch."); return ; }
pDrawingSketch->Edit();
CComPtr<SketchLines> pSketchLines; pDrawingSketch->get_SketchLines(&pSketchLines); if (FAILED(hRes)) { ShowCOMError (hRes,L"ASTI, could not get sketch lines."); return ; }
CComPtr<TransientGeometry> pTrGeom = GetTransGeomPtr() ;
91Programming Inventor in C++
(C) 2021 Owen F Ransen
for (int iDegs = 0; iDegs < 360; iDegs+=15) { CComPtr<Point2d> pStartPoint; pTrGeom->CreatePoint2d(0.0,0.0,&pStartPoint);
const double x = 100 * cos(RadsFromDegs(iDegs)); const double y = 100 * sin(RadsFromDegs(iDegs));
CComPtr<Point2d> pEndPoint; pTrGeom->CreatePoint2d(x,y,&pEndPoint);
pSketchLines->AddByTwoPoints((IDispatch*)pStartPoint,(IDispatch*)pEndPoint); }
CComPtr<Point2d> pTextPos,pDimPos1,pDimPos2; hRes = pTrGeom->CreatePoint2d(1.0,3.0,&pTextPos);
CComBSTR TestText(L"Hello"); CComVariant StyleName(L"Note Text (ISO)");
hRes = pDrawingSketch->TextBoxes->AddFitted(pTextPos, TestText,StyleName); if (FAILED(hRes)) { ShowCOMError (hRes,L"ASTI, AddFitted failed."); return ; }
pDrawingSketch->ExitEdit(); // Close the sketch editing
You'll get this, note the origin and that it is not clipped.
92 Autodesk Inventor Programming in C++ by Owen Ransen
(C) 2021 Owen F Ransen
The first part of the above code can be encapsulated as shown here.
12.34 Constrain a sketch point to a coordinate
This function can be used to add sketch points in defined xy positionsin a 2d sketch:
93Programming Inventor in C++
(C) 2021 Owen F Ransen
Note that AddTwoPointDistance uses the "initial" positions of the points towork out the distance and thus fix them with a dimension constraint.
// Given a sketch and a horizontal and vertical position this function addstwo // points, one at the origin of the sketch and the other constrained to theposition// in the parametersvoid AddConstrainedPointWRTOrigin(CComPtr<PlanarSketch>& pNewSketch,
94 Autodesk Inventor Programming in C++ by Owen Ransen
(C) 2021 Owen F Ransen
const double kxmmPos, const double kymmPos){ CComPtr<TransientGeometry> pTrGeom = GetTransGeomPtr();
// This will be a point fixed (grounded) at the origin... CComPtr<Point2d> pOrigin2d; pTrGeom->CreatePoint2d(0.0,0.0,&pOrigin2d); CComPtr<SketchPoint> pSketchOrigin; HRESULT hr = pNewSketch->SketchPoints->Add(pOrigin2d, VARIANT_FALSE,&pSketchOrigin);
CComPtr<GeometricConstraints> pGeoCons; hr = pNewSketch->get_GeometricConstraints(&pGeoCons);
// Fix the sketch point... CComQIPtr<SketchEntity> pSkEnt(pSketchOrigin); hr = pGeoCons->AddGround (pSkEnt); // !!!IMPORTANT!!! to make the originfixed
// Sketches work in cm so convert to cm from mm.... const double kcmxPos = kxmmPos / 10.0; const double kcmyPos = kymmPos / 10.0;
// The new point will be added to the sketch and constrained... CComPtr<Point2d> pNewPoint2d; pTrGeom->CreatePoint2d(kcmxPos,kcmyPos,&pNewPoint2d); CComPtr<SketchPoint> pNewSketchPointA ; hr = pNewSketch->SketchPoints->Add(pNewPoint2d, VARIANT_FALSE,&pNewSketchPointA); if (FAILED(hr)) { gLogger.Printf(ekErrMsg, L"Could not add sketch point"); return; }
// Work out a good point for the text of the dimension double xText = kcmxPos * 0.9; double yText = kcmyPos / 2.0; CComPtr<Point2d> pVTextPoint; pTrGeom->CreatePoint2d(xText,yText,&pVTextPoint);
hr = pNewSketch->DimensionConstraints->AddTwoPointDistance(pSketchOrigin, pNewSketchPointA, DimensionOrientationEnum::kVerticalDim, pVTextPoint, VARIANT_FALSE); if (FAILED(hr)) { ShowCOMError(hr, L"Could not add constraint AddTwoPointDistancevertical"); return; }
95Programming Inventor in C++
(C) 2021 Owen F Ransen
xText = kcmxPos / 2.0 ; yText = kcmxPos * 0.9 ; CComPtr<Point2d> pHTextPoint; hr = pTrGeom->CreatePoint2d(xText,yText,&pHTextPoint); if (FAILED(hr)) { ShowCOMError(hr, L"Could not add CreatePoint2d"); return; }
hr = pNewSketch->DimensionConstraints->AddTwoPointDistance(pSketchOrigin, pNewSketchPointA, DimensionOrientationEnum::kHorizontalDim, pHTextPoint, VARIANT_FALSE); if (FAILED(hr)) { ShowCOMError(hr, L"Could not add constraint AddTwoPointDistancehorizontal"); return; }}
text here.
12.35 Get a Document from a Definition
If you have a Part or Assembly definition, but not, for some reason,its Document you can use get_Document:
// Here is the definition obtained from somwhere... pDef = CComQIPtr<PartComponentDefinition>(pCompOcc->Definition); // Here is where you put the document you are after... CComPtr<PartDocument> pDoc ; pDef->get_Document((IDispatch**)&pDoc);
All the above is without checking for nullptr or HRESULT, you maywant to do it. And it uses Part. You can use Assembly in the sameway. Note also the (IDispatch**) cast.
96 Autodesk Inventor Programming in C++ by Owen Ransen
(C) 2021 Owen F Ransen
12.36 CreateSafeStringArray and CreateSafeDoubleArray
This is useful in various parts of COM programming:
// Call SafeArrayDestroy after you've finished with the arraySAFEARRAY* CreateSafeStringArray(long nElements, TCHAR *elements[]){ SAFEARRAYBOUND saBound[1];
saBound[0].cElements = nElements; saBound[0].lLbound = 0;
SAFEARRAY *pSA = SafeArrayCreate(VT_BSTR, 1, saBound);
if (pSA == NULL) { return NULL; }
for (int ix = 0; ix < nElements; ix++) { BSTR pData = SysAllocString(elements[ix]);
long rgIndicies[1];
rgIndicies[0] = saBound[0].lLbound + ix;
HRESULT hr = SafeArrayPutElement(pSA, rgIndicies, pData); }
return pSA;}
For example in adding tables into sheets.
For doubles use:
// After use call SafeArrayDestroySAFEARRAY* CreateSafeDoubleArray(long nElements, double* pElements){ SAFEARRAYBOUND rgsabound[1]; rgsabound[0].lLbound = 0; // index starts at 0 rgsabound[0].cElements = nElements; // number of elements
SAFEARRAY FAR* psa = SafeArrayCreate(VT_R8, 1, rgsabound); if (psa == NULL) { return 0; }
HRESULT hr = SafeArrayLock(psa);
for (int i = 0 ; i < nElements ; i++) { LONG rgIndex = i ;
97Programming Inventor in C++
(C) 2021 Owen F Ransen
double d = pElements[i]; hr = SafeArrayPutElement(psa, &rgIndex, &d); }
hr = SafeArrayUnlock(psa);
return psa;}
Here's an example.
12.37 Listing 2d points in a sketch
To get hold of the coordinates of 2d points in a 2d sketch look at thisexample:
gLogger.Printf(ekLogMsg, L"There are %d points in the sketch", pNewSketch->SketchPoints->Count); for (long p = 1; p <= pNewSketch->SketchPoints->Count; p++) { CComPtr<SketchPoint> pTempSketchPoint; pNewSketch->SketchPoints->get_Item(p,&pTempSketchPoint); CComPtr<Point2d> pCoords; pTempSketchPoint->get_Geometry(&pCoords); gLogger.Printf(ekLogMsg, L"Point %3d is %.2f %.2f",p, pCoords->GetX(),pCoords->GetY()); }
12.38 gkVarEmpty
This is used in various calls where you want an empty parameter:
const CComVariant gkvarEmpty ; // Used in various COM calls here
12.39 Add an iMate (based on a point) into an assembly
Here is a function to do it:
bool AddMateiMateAtAsmWorkPoint(const CString& kcsiMateName, CComPtr<AssemblyComponentDefinition>pAsmCompDef, const CString& kcsWorkPointName)
98 Autodesk Inventor Programming in C++ by Owen Ransen
(C) 2021 Owen F Ransen
{ CComPtr<iMateDefinitions> piMateDefinitions = nullptr ; HRESULT hRes = pAsmCompDef->get_iMateDefinitions(&piMateDefinitions); if (FAILED(hRes)) { TRACE ("AMMAAWP: Failed to get iMate definitions"); return false ; }
CComPtr<WorkPoint> pWorkPoint; const bool kbWpOk = GetWorkPointByName(pWorkPoint, kcsWorkPointName,pAsmCompDef); if (!kbWpOk) { TRACE ("AMMAAWP: Failed to get work point called <%s>",kcsWorkPointName); return false; }
// Zero offset CComVariant varOffset = CComVariant(0.0);
CComPtr<MateiMateDefinition> pMateiMateDef; hRes = piMateDefinitions->AddMateiMateDefinition(pWorkPoint, varOffset, kNoInference, gkvarEmpty, CComBSTR(kcsiMateName), gkvarEmpty, &pMateiMateDef); if (FAILED(hRes)) { TRACE (L"AMMAAWP:Failed to add iMate definition at work point.",kcsWorkPointName); return false; }
return true;}
Here is some example code which also opens the assembly...
CComPtr<AssemblyComponentDefinition> pAsmCompDef; CComPtr<AssemblyDocument> pAsmDoc; const CString kcsFullAsmFileName(L"C:\\TEST.IAM") ;
const bool kbOpenedOk = OpenAssembly(pAsmCompDef,pAsmDoc,kcsFullAsmFileName) ; if (!kbOpenedOk) { TRACE("Failed to open"); return; }
CComPtr<iMateDefinitions> piMateDefinitions = nullptr ; HRESULT hRes = pAsmCompDef->get_iMateDefinitions(&piMateDefinitions); if (FAILED(hRes)) {
99Programming Inventor in C++
(C) 2021 Owen F Ransen
TRACE("Failed to get imate definitions"); return; }
CComPtr<WorkPoint> pWorkPoint; const bool kbWpOk = GetWorkPointByName(pWorkPoint, L"ZeroPoint",pAsmCompDef); if (!kbWpOk) { TRACE("Could not find work point"); return; }
CComVariant varOffset = CComVariant(0.0);
CComPtr<MateiMateDefinition> pMateiMateDef; hRes = piMateDefinitions->AddMateiMateDefinition(pWorkPoint, varOffset, kNoInference, gkvarEmpty, CComBSTR("Pippo"), gkvarEmpty, &pMateiMateDef); if (FAILED(hRes)) { TRACE("Failed to add imate definition."); }
pAsmDoc->Close(VARIANT_FALSE);
See what I mean?
12.40 Part Lists programatically
Here you get an existing Part List and add a row to it:
// There can be many part lists in a single sheet, get hold of thelist of lists... CComPtr<PartsLists> pPartsLists; hRes = pSheet->get_PartsLists(&pPartsLists);
// Make a 2d point to specify the top left corner of the partslist... CComPtr<TransientGeometry> pTransGeom = GetTransGeomPtr () ; CComPtr<Point2d> pListPos; // Create a 2d point
// Place top left of part list in the center of the sheet... pTrGeom->CreatePoint2d(SheetWidth/2.0,SheetWidth/2.0,&pListPos);
// To create a part list you add it to the list of part lists.... CComPtr<PartsList> MyPartList; CComVariant varNumNum(kNumericNumbering); hRes = pPartsLists->Add(pBaseView1, pListPos, kFirstLevelComponents,varNumNum, 1, VARIANT_FALSE, &MyPartList);
100 Autodesk Inventor Programming in C++ by Owen Ransen
(C) 2021 Owen F Ransen
// A part list is in essence a set of rows... PartsListRowsPtr pRows = MyPartList->GetPartsListRows(); long iNumRows = pRows->Count;
// Add a new row. // This new row will have the same number of columns as existing rows CComPtr<PartsListRow> pNewRow; hRes = pRows->Add(iNumRows, // Relative to which existing row weinsert the new one? VARIANT_FALSE, // FALSE means insert after theexsiting roe &pNewRow); // Returned new row long iNumCols; pNewRow->get_Count(&iNumCols); if (iNumCols >= 4) { // Test adding text into col 3 // Col1 is id, 2 is quantity, they have default values 3 and 4 youfill out CComPtr<PartsListCell> pCell; CComVariant ColNum(3); pNewRow->get_Item(ColNum, &pCell); CComBSTR Hello(L"Hello you"); pCell->put_Value(Hello); }
So you have to get hold of the cell and then modify it.
101Programming Inventor in C++
(C) 2021 Owen F Ransen
12.41 Add an assembly into another assembly programatically
Here is the code to do that:
HRESULT AddAssemblyToAssemblyAtPosition (CComPtr<AssemblyComponentDefinition>& pParentAsmDef, const CString& kcsFullPathAsmName, const double kxPos, const double kyPos, const double kzPos, CComPtr<ComponentOccurrence>& pChildAsmOcc, CComQIPtr<AssemblyComponentDefinition>& pChildAsmDef, const double kxRotDegs /*=0.0*/, const double kyRotDegs /*=0.0*/, const double kzRotDegs /*=0.0*/) /*The positions are in the natural units of Inventor, usually cmWe return the occurence and its part component definition*/{ pChildAsmOcc = nullptr ;
CComPtr<ComponentOccurrences> pOccurrencesList = nullptr; HRESULT hRes = pParentAsmDef->get_Occurrences (&pOccurrencesList) ; if (FAILED(hRes)) { return ReturnAndShowCOMError (hRes,L"AddAssemblyToAssemblyAtPosition get_Occurrences failed") ; }
CComPtr<TransientGeometry> pTransGeom = GetTransGeomPtr () ; CComPtr<Matrix> pPosMatrix; pTransGeom->CreateMatrix(&pPosMatrix);
CComPtr<Vector> pVector; // Create a Vector to modify the Matrix pTransGeom->CreateVector(kxPos,kyPos,kzPos,&pVector);
// Make the matrix a "move to point" matrix... pPosMatrix->SetTranslation (pVector,VARIANT_TRUE) ;
CComPtr<Matrix> pPosRotMatrix ; pTransGeom->CreateMatrix(&pPosRotMatrix);
CComPtr<Vector> pZAxis ; hRes = pTransGeom->CreateVector (0,0,1,&pZAxis); if (FAILED(hRes)) { ShowCOMError (hRes,L"Could not create z axis vector") ; return false ; }
CComPtr<Point> pOrigin ; hRes = pTransGeom->CreatePoint (0,0,0,&pOrigin);
102 Autodesk Inventor Programming in C++ by Owen Ransen
(C) 2021 Owen F Ransen
const double kZRadsRot = RadsFromDegs(kzRotDegs); pPosRotMatrix->SetToRotation (kZRadsRot,pZAxis,pOrigin) ;
pPosRotMatrix->PreMultiplyBy(pPosMatrix);
hRes = pOccurrencesList->Add (CComBSTR(kcsFullPathAsmName),pPosRotMatrix,&pChildAsmOcc) ; if (FAILED(hRes)) { return ReturnAndShowCOMError (hRes,L"AddAssemblyToAssemblyAtPosition Add failed") ; }
// Get the general component definition... CComQIPtr<ComponentDefinition> pCompDef ; hRes = pChildAsmOcc->get_Definition (&pCompDef) ; if (FAILED(hRes)) { return ReturnAndShowCOMError (hRes,L"AddAssemblyToAssemblyAtPosition could not get child definition.") ; }
// Cast from the general sort of component definition to the specific assembly component definition pChildAsmDef = CComQIPtr<AssemblyComponentDefinition>(pCompDef); if (pChildAsmDef == nullptr) { gLogger.Printf (ekErrMsg,L"AddAssemblyToAssemblyAtPosition(%s) could not cast to pChildAsmDef.") ; return E_FAIL ; }
return S_OK ;}
Enter topic text here.
12.42 Hide a sketch in a part
You can yse this function:
void HidePartSketchByName (CComPtr<PartComponentDefinition>& pPartCompDef,const wchar_t* const pszName){ // Get the list of sketches... CComPtr<PlanarSketches> pSketchesList ; HRESULT hRes = pPartCompDef->get_Sketches(&pSketchesList) ; if (FAILED(hRes)) { ShowCOMError(hRes,L"HPSBN (%s) get_Features failed",pszName); return ; }
CComPtr<PlanarSketch> pSketch ; hRes = pSketchesList->get_Item (CComVariant(pszName),&pSketch) ;
103Programming Inventor in C++
(C) 2021 Owen F Ransen
if (FAILED(hRes)) { gLogger.Printf(ekLogMsg, L"HPSBN (%s) get_Item failed, sketch hasalready been deleted maybe", pszName); return ; }
pSketch->put_Visible (VARIANT_FALSE) ;}
12.43 Range BBox of a PartsList
Notice that you declare the Box2d but don't must not make it withpTrGeom->CreateBox2d(&BBoxOfLists);. In other words get_RangeBox expectsa null input and he hands you back the created box.
// Find out the size of the bounding box CComPtr<Box2d> BBoxOfLists; // Inits to nullptr MyPartsList->get_RangeBox(&BBoxOfLists);
gLogger.Printf(ekLogMsg, L"Bbox = %.2f %.2f %.2f %.2f ", BBoxOfLists->GetMinPoint()->GetX(), BBoxOfLists->GetMinPoint()->GetY(), BBoxOfLists->GetMaxPoint()->GetX(), BBoxOfLists->GetMaxPoint()->GetY());
12.44 Add a unitless user parameter into an assembly
Here's a function to do that:
// Adds a unitless user parameter and its value into an assembly... void AddUserUlParamToAssembly(CComPtr<AssemblyComponentDefinition>&pAssemblyCompDef, const CString& kcsParamName, const double kParamValue){ // Parameters contains two lists, Model and User... CComPtr<Parameters> pParameters ; pAssemblyCompDef->get_Parameters (&pParameters) ;
// Get the model parameters list... CComPtr<UserParameters> pUserParameters ; pParameters->get_UserParameters (&pUserParameters) ;
CComVariant varValue(kParamValue); CComVariant varUnits(L"ul");
104 Autodesk Inventor Programming in C++ by Owen Ransen
(C) 2021 Owen F Ransen
CComBSTR bstrVarName(kcsParamName);
HRESULT hRes = pUserParameters->AddByValue(bstrVarName, varValue,varUnits); if (FAILED(hRes)) { TRACE (L"Could not add user parameter <%s> to assembly", kcsParamName); }}
It seems like you cannot specify int or double, all parameters aredoubles.
12.45 Create an ObjectCollection of parts in an assembly
You won't have all the functions here, you'll have to adapt it, but youget the idea:
CComPtr<ObjectCollection> CreateCollectionOfCctObjects(CComPtr<AssemblyComponentDefinition> pAssemblyCompDef, const CctTypeFlags_t ikObjectsToCollect){ // Make an ObjectCollection of all object typesspecified... CComPtr<TransientObjects> pTransObjs =GetTransientObjectsPtr() ;
CComPtr<ObjectCollection> pObjCollection = nullptr ; HRESULT hRes = pTransObjs->CreateObjectCollection(gkvarEmpty,&pObjCollection) ; if (FAILED(hRes)) { gLogger.Printf (ekErrMsg,L"CCOCO,CreateObjectCollection failed.") ; return nullptr ; }
// Get ALL the occurrences in the assembly... CComPtr<ComponentOccurrences> pOccurrences = nullptr; hRes = pAssemblyCompDef->get_Occurrences (&
105Programming Inventor in C++
(C) 2021 Owen F Ransen
pOccurrences) ; if (FAILED(hRes)) { gLogger.Printf (ekErrMsg,L"CCOCO,get_Occurrences failed.") ; return nullptr ; }
// Collect together only the occurrences we areinterested in... for (int i = 1; i <= pOccurrences->Count; i++) { CComPtr<ComponentOccurrence> pThisCompOcc =nullptr ; hRes = pOccurrences->get_Item(i, &pThisCompOcc);
_bstr_t DisplayName = pThisCompOcc->Get_DisplayName(); CString kcsDisplayName = CString(DisplayName.GetBSTR());
const CString kcsSapCode = kcsDisplayName.Left(NUM_SAP_CHARS);
const bool kbObjToActOn = SapCodeIsA(kcsSapCode, ikObjectsToCollect) ; if (kbObjToActOn) { pObjCollection->Add(pThisCompOcc); } }
return pObjCollection;}
Can be used to create an ObjectCollection of ParticipatingOccurrences.
106 Autodesk Inventor Programming in C++ by Owen Ransen
(C) 2021 Owen F Ransen
12.46 Delete a feature in a part
It is a bit delicate if other features depend on the feature you aretrying to delete.
void DeletePartFeatureByName(CComPtr<PartComponentDefinition>& pPartCompDef,const wchar_t* const pszName){ // Get the list of features... CComPtr<PartFeatures> pFeaturesList = nullptr ; HRESULT hRes = pPartCompDef->get_Features(&pFeaturesList) ; if (FAILED(hRes)) { ShowCOMError(hRes,L"DPFBN get_Features failed"); return ; }
CComPtr<PartFeature> pFeature = nullptr ; hRes = pFeaturesList->get_Item (CComVariant(pszName),&pFeature) ; if (FAILED(hRes)) { ShowCOMError(hRes,L"DPFBN get_Item(%s) failed",pszName); return ; }
hRes = pFeature->Delete(VARIANT_FALSE,VARIANT_FALSE,VARIANT_FALSE); if (FAILED(hRes)) { ShowCOMError(hRes,L"DPFBN Delete(%s) failed",pszName); }}
12.47 Loop over part occurences in an assembly
Here's an example, which also shows the use of _b_str_t andDisplayName and the filename of the part:
CComPtr<ComponentOccurrences> pOccurrences; hRes = pAssemblyCompDef->get_Occurrences (&pOccurrences) ;
// Note the i starts at 1, NET counting for (int i = 1; i <= pOccurrences->Count; i++) { CComPtr<ComponentOccurrence> pThisCompOcc ; hRes = pOccurrences->get_Item(i, &pThisCompOcc);
_bstr_t DisplayName = pThisCompOcc->Get_DisplayName(); CString csDisplayName = CString (DisplayName.GetBSTR());
CComPtr<DocumentDescriptor> pDocDesc ; pThisCompOcc->get_ReferencedDocumentDescriptor(&pDocDesc) ; CComBSTR bstrFullDocName ;
107Programming Inventor in C++
(C) 2021 Owen F Ransen
pDocDesc->get_FullDocumentName (&bstrFullDocName) ; gLogger.Printf(ekLogMsg, L"Occ <%s> Disp=<%s>",CString(bstrFullDocName), csDisplayName); }
The DisplayName is what appears in the tree list of the assembly, bythe way. The output in the display name also includes the number ofthe part inserted, after the ":"
Occurrence <C:\Owen\DirA\Curve_Rame_12\30091328.ipt> Display=<30091328:17>Occurrence <C:\Owen\DirA\Forcelle_Rame_12_Rigato\30093874.ipt>Display=<30093874:22>Occurrence <C:\Owen\DirA\Curve_Rame_12\30091327.ipt> Display=<30091327:18>Occurrence <C:\Owen\DirA\Forcelle_Rame_12_Rigato\30093882.ipt>Display=<30093882:23>
108 Autodesk Inventor Programming in C++ by Owen Ransen
(C) 2021 Owen F Ransen
12.48 Add a rectangle to a sketch
Here's a function to add a rectangle to a sketch:
bool AddRectToSketch (CComPtr<PlanarSketch>& pSketch, const double kxMin, const double kyMin, const double kxMax, const double kyMax) { // Get the transient geometry object. We'll use this to create pure geometric points CComPtr<TransientGeometry> pTrGeom = GetTransGeomPtr() ; CComPtr<Point2d> pMinPt; // Pure geometric point HRESULT hRes = pTrGeom->CreatePoint2d(kxMin,kyMin,&pMinPt); CComPtr<Point2d> pMaxPt; // Pure geometric point hRes = pTrGeom->CreatePoint2d(kxMax,kyMax,&pMaxPt);
// Create sketch points from above points // Get list of SketchPoints, points existing in a sketch CComPtr<SketchPoints> pSkPoints;
hRes = pSketch->get_SketchPoints(&pSkPoints);
// Create a SketchPoint from a geometric point CComPtr<SketchPoint> pSpt1; hRes = pSkPoints->Add(pMinPt, // geometrical point VARIANT_FALSE, // not a hole center &pSpt1); // resulting SketchPoint
CComPtr<SketchPoint> pSpt2; hRes = pSkPoints->Add(pMaxPt,VARIANT_FALSE,&pSpt2); CComPtr<SketchEntitiesEnumerator> pRectangleLines;
// Get SketchLines CComPtr<SketchLines> pSkLines; hRes = pSketch->get_SketchLines(&pSkLines);
// Creat a rectangle from two points hRes = pSkLines->AddAsTwoPointRectangle(_variant_t((IDispatch *)pSpt1), _variant_t((IDispatch *)pSpt2), &pRectangleLines);
return SUCCEEDED(hRes) ;}
109Programming Inventor in C++
(C) 2021 Owen F Ransen
12.49 Rectangular cut with extrusion
Here is what I use, complete with optional participating occurrencesObjectCollection:
bool ExtrudeSketchInAsm (const wchar_t* const pszExtrusionName, // name ofcreated feature const double kHeight, const wchar_t* const pszSketchName, // whichsketch to extrude const PartFeatureOperationEnum eOperation, // how toextrude const PartFeatureExtentDirectionEnum eDirection, CComPtr<AssemblyComponentDefinition>& pAsmCompDef, CComPtr<ObjectCollection> pParticipatingObjects /* =nullptr*/)/*Given a height and a sketch name the sketch is extruded to the given height.The resultant feature is placed inside pAsmCompDef, and is calledpszExtrusionNameeOperation tells us whether to cut a hole or create a solid object etc.eDirection tells us which direction to make the extrusion.If pParticipatingObjects is nullptr all occurrences in the assembly areaffected.If pParticipatingObjects is a list of occurrences ony thos occurrences areaffected.*/{ gLogger.Printf (ekLogMsg,L"ESIA extrusion called %s, height %.2fmm,sketch=%s\n", pszExtrusionName,kHeight,pszSketchName) ;
// Get the sketch in the part by name... CComPtr<PlanarSketch> pSketch; HRESULT hRes = pAsmCompDef->Sketches->get_Item(CComVariant(pszSketchName),&pSketch); if (FAILED(hRes)) { ShowCOMError (hRes,L"ESIA, but could not get sketch by name: <%s>\n",pszSketchName); return false ; } CComPtr<Profile> pProfile ; // This is the return value of the call toAddForSolid // and will be used when we extrude. CComVariant pSegs; // not used CComVariant pReserve; // not used hRes = pSketch->Profiles->AddForSolid(VARIANT_TRUE,pSegs,pReserve,&pProfile); if (FAILED(hRes)) { ShowCOMError (hRes,L"ESIA, but could not AddForSolid for pProfile\n");
110 Autodesk Inventor Programming in C++ by Owen Ransen
(C) 2021 Owen F Ransen
return false ; }
// Features are 3D objects. Get the list of them so we can add to thatlist... CComPtr<Features> pListOfFeatures=nullptr; hRes = pAsmCompDef->get_Features(&pListOfFeatures); if (FAILED(hRes)) { ShowCOMError (hRes,L"ESIA, but could not get_Features\n"); return false ; }
// Get the list of *extruded* features... CComPtr<ExtrudeFeatures> pListOfExtrusions; hRes = pListOfFeatures->get_ExtrudeFeatures(&pListOfExtrusions); if (FAILED(hRes)) { ShowCOMError (hRes,L"ESIA, but could not get_ExtrudeFeatures\n"); return false ; }
// Now at last we can use the pProfile to create a new extrusion, addingit to the list // of extruded features. This is where we use the eOperation parameter CComPtr<ExtrudeDefinition> pExtrudeDef; hRes = pListOfExtrusions->CreateExtrudeDefinition(pProfile,eOperation,&pExtrudeDef); if (FAILED(hRes)) { ShowCOMError (hRes,L"ESIA, but could not CreateExtrudeDefinition\n"); return false ; }
// Specify the distance and direction of the extrustion... pExtrudeDef->SetDistanceExtent(_variant_t(kHeight),eDirection);
if (pParticipatingObjects != nullptr) { hRes = pExtrudeDef->put_AffectedOccurrences(pParticipatingObjects); if (FAILED(hRes)) { ShowCOMError (hRes,L"ESIA, but could not put_AffectedOccurrencesfor <%s>\n",pszExtrusionName); return false ; } }
// Add the extrusion. CComPtr<ExtrudeFeature> pExtrude = nullptr ; hRes = pListOfExtrusions->Add (pExtrudeDef,&pExtrude); if (FAILED(hRes)) { ShowCOMError (hRes,L"ESIA, but could not Add ExtrudeDefinition for<%s>\n" L"***LISTEN*** This can happen if the extrusion does notchange the model.",pszExtrusionName); return false ; }
111Programming Inventor in C++
(C) 2021 Owen F Ransen
pExtrude->put_Name (CComBSTR (pszExtrusionName)) ;
return true ;}
12.50 WorkAxis constraints
To constrain two axes together programatically you can use thisfunction:
bool AddMateConstraintOfTwoWorkAxisProxies (CComPtr<AssemblyComponentDefinition>& pAsmCompDef, CComPtr<WorkAxisProxy>& pWAProxyA, CComPtr<WorkAxisProxy>& pWAProxyB, const double kRadiusMm /*=0.0*/) { // Get the list of constraints of the assembly so you can add a new one CComPtr<AssemblyConstraints> pConstraintList = nullptr ; HRESULT hRes = pAsmCompDef->get_Constraints(&pConstraintList) ; if (FAILED(hRes) || (pConstraintList == nullptr)) { ShowCOMError (hRes,L"AddMateConstraintOfTwoWorkAxisProxies could notget constraints.") ; return false ; }
// The offset in a axis constraint is a radius about which the axes // can rotate. Having a non zero one means a bit more flexiblity. CComVariant varOffset(kRadiusMm/10.0); // in cm
CComPtr<MateConstraint> pMateConstraint = nullptr ; hRes = pConstraintList->AddMateConstraint(pWAProxyA, pWAProxyB, varOffset, kNoInference, kNoInference, gkvarEmpty, gkvarEmpty, &pMateConstraint); if ((FAILED(hRes) || (pMateConstraint == nullptr))) { ShowCOMError (hRes,L"AddMateConstraintOfTwoWorkAxisProxies failed") ; return false ; }
return true ;}
Explanation of kRadiusMm here.
112 Autodesk Inventor Programming in C++ by Owen Ransen
(C) 2021 Owen F Ransen
12.51 Getting hold of the standard workpoint called "Center Point"
Here's an example of getting it and using it:
// Get the point in the manicotto CComPtr<WorkPoint> pWorkPointInMani ; hRes = GetWorkPointByName (pWorkPointInMani,L"Center Point",pManicottoCompDef) ;
AddMateConstraintOfTwoPoints (pAssemblyCompDef, pTuboOcc, pWorkPointInColl, pManicottoOcc, pWorkPointInMani) ;
I also call it an origin point or a zero point.
12.52 Add a WorkPoint into an assembly programatically
Here's how to do it, but note that the point added is totallyunconstrained:
CComPtr<WorkPoints> pWorkPointsList ; hRes = pAssemblyCompDef->get_WorkPoints (&pWorkPointsList) ;
CComPtr<Point> pPt; // Create a 3d point hRes = GetTransGeomPtr()->CreatePoint(kStart[XI],kStart[YI],kStart[ZI],&pPt);
hRes = pWorkPointsList->AddFixed (pPt,FALSE) ;
There's no error checking in the above code.
To do it manually you need to create a point which is the intersectionof 3 planes (x y z). The planes can be offset of course so you are ableto put the plane anywhere in 3D space.
Here is code which illustrates putting it at the start of an axis andsetting its name:
// Get the geometry of the axis.. LinePtr pLine = pNodeWAZProxy->GetLine() ; PointPtr pProxyOrigin = pLine->RootPoint ; UnitVectorPtr pDir = pLine->Direction ;
// You can get hold of the double values like this... TRACE("pos = %.3f, %.3f, %.3f, dir = %.3f, %.3f, %.3f,\n", pProxyOrigin->GetX(),pProxyOrigin->GetY(),pProxyOrigin->GetZ(), pDir->GetX(), pDir->GetY(), pDir->GetZ());
113Programming Inventor in C++
(C) 2021 Owen F Ransen
CComPtr<WorkPoints> pWorkPointsList ; hRes = pCctsAssemblyCompDef->get_WorkPoints (&pWorkPointsList) ; CComPtr<Point> pPt; // Create a 3d point hRes = GetTransGeomPtr()->CreatePoint(pProxyOrigin->GetX(), pProxyOrigin->GetY(), pProxyOrigin->GetZ(),&pPt); CComPtr <WorkPoint> pWorkPoint; hRes = pWorkPointsList->AddFixed (pPt,FALSE,&pWorkPoint) ;
const CTime kNow = CTime::GetCurrentTime (); CString csPointName; csPointName.Format(L"TUBO_%d_%d", kNow.GetSecond(), rand());
CComBSTR bstrName(csPointName);
pWorkPoint->put_Name(bstrName);
12.53 Add a WorkPoint at the intersection of a line and a plane
Here's a fragment (no error checking) which explains how to do it...
// Get the proxy of the axis CComPtr<WorkAxisProxy> pNodeWAZProxy ; ZAxisArray[1]->get_Item(2,(IDispatch**)&pNodeWAZProxy);
CComPtr<TransientGeometry> pTransGeom = GetTransGeomPtr () ;
LinePtr pLine = pNodeWAZProxy->GetLine(); PointPtr pLineRoot = pLine->GetRootPoint(); UnitVectorPtr pLineDir = pLine->GetDirection(); CComPtr <Vector> pvecDir ; hRes = pLineDir->AsVector(&pvecDir);
CComPtr <Line> pZAxis; hRes = pTransGeom->CreateLine (pLineRoot,pvecDir,&pZAxis);
CComPtr<Point> pOrigin; CComPtr<Point> p1; CComPtr<Point> p2;
// Create 3 points in the XY plane... pTransGeom->CreatePoint(0, 0, 0, &pOrigin); pTransGeom->CreatePoint(1, 0, 0, &p1); pTransGeom->CreatePoint(0, 1, 0, &p2);
// Create the plane with 3 points... CComPtr<Plane> pGeomXYPlane; hRes = pTransGeom->CreatePlaneByThreePoints(pOrigin, p1, p2, &pGeomXYPlane);
// In general there could me many intersections of a line and a
114 Autodesk Inventor Programming in C++ by Owen Ransen
(C) 2021 Owen F Ransen
surfaces, // With a plane we expeect pObjEnum to contain a single object CComPtr <ObjectsEnumerator> pObjEnum; hRes = pTransGeom->CurveSurfaceIntersection(pZAxis, pGeomXYPlane,0.1, &pObjEnum);
TRACE ("There are %d intersections...\n",pObjEnum->Count);
if (pObjEnum->Count < 1) { gLogger.Printf(ekErrMsg, "No intersections found..."); return; }
CComPtr <Point> pIntersectionPoint; hRes = pObjEnum->get_Item(1,(IDispatch**)&pIntersectionPoint);
TRACE("Intersection at %.2f %.2f %.2f \n", pIntersectionPoint->GetX(), pIntersectionPoint->GetY(), pIntersectionPoint->GetZ());
CComPtr<WorkPoints> pWorkPoints; hRes = pAssemblyCompDef->get_WorkPoints(&pWorkPoints);
CComPtr <WorkPoint> pInterWorkPoint; pWorkPoints->AddFixed (pIntersectionPoint,FALSE,&pInterWorkPoint);
CComBSTR bstrPointName("ZeroPoint"); hRes = pInterWorkPoint->put_Name(bstrPointName);
12.54 Add grounded WorkAxis in an assembly
There are limits to how you can add work axes in assemblies (andpresumably also work points and work planes). In general they haveto be done using AddFixed.
Here's an example:
CComQIPtr<AssemblyDocument> pAssemblyDoc; CComPtr<AssemblyComponentDefinition> pAssemblyCompDef;
CComPtr<TransientGeometry> pTransGeom = GetTransGeomPtr();
CComPtr<Application>pApp = theApp.GetInvAppPtr();
CreateNewAssembly(pAssemblyDoc, pAssemblyCompDef,strTemplateFile);
115Programming Inventor in C++
(C) 2021 Owen F Ransen
CComPtr<WorkAxes> pAsmWorkAxes; pAssemblyCompDef->get_WorkAxes(&pAsmWorkAxes);
for (int ix = 0; ix < 3; ix++) { double x = ix * 3; for (int iy = 0; iy < 3; iy++) { double y = iy * 3; CComPtr<UnitVector> pUnitVec; pTransGeom->CreateUnitVector(0, 0, 1.0, &pUnitVec);
CComPtr<Point> pPoint; pTransGeom->CreatePoint(x, y, 0.0, &pPoint);
CComPtr<WorkAxis> pNewAxis; pAsmWorkAxes->AddFixed(pPoint, pUnitVec,VARIANT_FALSE,&pNewAxis); pNewAxis->put_Grounded(VARIANT_TRUE); } }
Here is an example which starts off with a WorkAxisProxy and adds aWorkAxis in that position.
CComPtr<TransientGeometry> pTransGeom = GetTransGeomPtr () ;
LinePtr pLine = pNodeWAZProxy->GetLine(); PointPtr pLineRoot = pLine->GetRootPoint(); UnitVectorPtr pLineDir = pLine->GetDirection(); CComPtr <Vector> pvecDir ; HRESULT hRes = pLineDir->AsVector(&pvecDir); if (FAILED(hRes)) { gLogger.Printf(ekErrMsg, "AWAART: Could not get AsVector"); return false ; }
CComPtr<WorkAxes> pWorkAxes; hRes =pCctsAsmCompDef->get_WorkAxes(&pWorkAxes); if (FAILED(hRes)) { gLogger.Printf(ekErrMsg, "AWAATR: Could not get workaxes"); return false ; }
116 Autodesk Inventor Programming in C++ by Owen Ransen
(C) 2021 Owen F Ransen
CComPtr<WorkAxis> pNewWorkAxis; pWorkAxes->AddFixed (pLineRoot,pLineDir,VARIANT_FALSE,&pNewWorkAxis) ; if (FAILED(hRes)) { ShowCOMError (hRes,L"AWAATR: AddFixed (%s) failed",kcsAxisName.GetString ()); return false ; }
CComBSTR bstrAxisName(kcsAxisName); hRes = pNewWorkAxis->put_Name(bstrAxisName); if (FAILED(hRes)) { gLogger.Printf(ekErrMsg,L"AWAATR: put_Name (%s) failed",LPWSTR(bstrAxisName)); return false ; }
Here is an example in VB:
Public Sub AssemblyWorkAxis() Dim asmDoc As AssemblyDocument Set asmDoc = ThisApplication.ActiveDocument Dim asmDef As AssemblyComponentDefinition Set asmDef = asmDoc.ComponentDefinition Dim tg As TransientGeometry Set tg = ThisApplication.TransientGeometry Dim wa As WorkAxis Set wa = asmDef.WorkAxes.AddFixed(tg.CreatePoint(0, 0, 0), _ tg.CreateUnitVector(1, 1,1)) wa.Grounded = TrueEnd Sub
117Programming Inventor in C++
(C) 2021 Owen F Ransen
12.55 List iMates in an assembly
Here's something which will list iMates in an assembly:
CComPtr<AssemblyComponentDefinition> pAsmCompDef; CComPtr<AssemblyDocument> pAsmDoc; const CString kcsFullAsmFileName(L"C:\\docs\TestAssembly.Iam") ;
const bool kbOpenedOk = OpenAssembly(pAsmCompDef,pAsmDoc,kcsFullAsmFileName) ; if (!kbOpenedOk) { TRACE("Failed to open"); return; }
CComPtr<iMateDefinitions> piMateDefinitions = nullptr ; HRESULT hRes = pAsmCompDef->get_iMateDefinitions(&piMateDefinitions); if (FAILED(hRes)) { TRACE("Failed to get imate definitions"); return; }
TRACE ("There are %d imate definitions\n",piMateDefinitions->GetCount());
for (int i = 1; i <= piMateDefinitions->GetCount(); i++) { CComPtr<iMateDefinition> piMateDef; piMateDefinitions->get_Item(i, &piMateDef);
_bstr_t bstrName = piMateDef->GetName(); CString csName1((wchar_t*)bstrName);
CComPtr<iMateDefinition> piMateDef2; piMateDef->get_ReferencedEntity(&piMateDef2);
TRACE(L"%d %s\n", i, csName1);
if (piMateDef2 != nullptr) { bstrName = piMateDef2->GetName(); CString csName2((wchar_t*)bstrName); TRACE(L" Referenced entity name = %s\n",csName2); }
CComPtr<ReferenceComponent> pRefComp; piMateDef->get_ReferenceComponent(&pRefComp); if (pRefComp != nullptr) { TRACE (L" Refernced component = %s\n",pRefComp->Name) ; }
const ObjectTypeEnum eObjType = piMateDef->GetType();
TRACE(L" Obj type is %d <%s>\n", eObjType, GetObjTypeDesc(eObjType)); }
pAsmDoc->Close(VARIANT_TRUE);
118 Autodesk Inventor Programming in C++ by Owen Ransen
(C) 2021 Owen F Ransen
12.56 Filename of referenced doc
The FullDocumentName seems to be the filename. Here's anexample
CComPtr<ComponentOccurrence> pThisCompOcc ;hRes = pOccurrencesList->get_Item(1, &pThisCompOcc);
if (FAILED(hRes) || (pThisCompOcc == nullptr)){ ShowCOMError(hRes,L"GetComponentOccurrenceByName, get_Item failed "); return ; }
// Now find out the part which this is a view of... CComPtr<DocumentDescriptor> pDocDesc ; pThisCompOcc->get_ReferencedDocumentDescriptor (&pDocDesc) ;
CComBSTR bstrFullDocName ; pDocDesc->get_FullDocumentName (&bstrFullDocName) ;
WalertBoxW (L"Referenced doc = %s",bstrFullDocName) ;
12.57 Referenced Document of a View
When you have a view you can get hold of the object the view islooking at. The object is called the referenced document, for exampleif it is a part:
119Programming Inventor in C++
(C) 2021 Owen F Ransen
Getting the referenced document can be useful for getting retrieveable dimensions.
Here is an example code fragment (with no error checking):
120 Autodesk Inventor Programming in C++ by Owen Ransen
(C) 2021 Owen F Ransen
// Now find out the part which this is a view of... CComPtr<DocumentDescriptor> pDocDesc ; pThisView->get_ReferencedDocumentDescriptor (&pDocDesc) ;
// Still finding out the part which this is a view of... CComPtr<Document> pReffedDoc ; pDocDesc->get_ReferencedDocument ((IDispatch**)&pReffedDoc) ;
if (kPartDocumentObject != pReffedDoc->DocumentType) { WalertBoxW (L"The referenced document is not a part") ; return ; }
// Convert the general referenced doc into a part doc... CComQIPtr<PartDocument> pPartDoc = pReffedDoc ;
So pPartDoc is the document which the view refers to.
12.58 put_Name, how to use it
If you have the name a wchar_t it seems that you must convert ot toa CComBSTR like this
CComBSTR bstrName = CString (pszSketchName) ; pNewSketch->put_Name (bstrName) ;
If you just use the wchar_t it does not seem to work.
12.59 Retrievable Dimensions
Retrievable dimensions are dimensions in the part (and maybe theassembly) which can be placed in the view. In the GUI you open anIDW, go into the Annotate ribbon and click on the Retrieve icon:
121Programming Inventor in C++
(C) 2021 Owen F Ransen
If you have two visible versions of the same dimension in differentviews (on the same sheet) only one view will get the dimension.
Programatically you use the functions GetRetrievableDimensions andRetrieveDimensions.
122 Autodesk Inventor Programming in C++ by Owen Ransen
(C) 2021 Owen F Ransen
Here's a function you can use when a part drawing (not an assemblydrawing) has been opened... though note that at the time of writing(July 2015) there seems to be a bug in the API when you try to getmore than one dimension singly.
123Programming Inventor in C++
(C) 2021 Owen F Ransen
void GetRetDimsOfPart (){ CComPtr<Application> pInvApp = theApp.GetInvAppPtr () ;
// Get all the documents which are open in Inventor... CComPtr<Documents> pDocuments; HRESULT hRes = pInvApp->get_Documents (&pDocuments) ;
if (FAILED(hRes) || (pDocuments == nullptr)) { TRACE (L"GetRetDimsOfPart, could not get docs") ; return ; }
// Find the first IDW document... const UINT ikNumDocs = pDocuments->Count ; if (ikNumDocs == 0) { TRACE (L"There should be at least one IDW documentopen\n" L"There are no documents open."); return ; }
// This will be non null after the for loop if an IDW drawingdocument is found CComQIPtr<DrawingDocument> pIDWDoc ; // Is null at the moment
for (UINT iDoc = 1 ; iDoc <= ikNumDocs ; iDoc) { CComPtr<Document> pDoc ; hRes = pDocuments->get_Item (1,&pDoc) ; if (FAILED(hRes) || (pDoc == nullptr)) { TRACE (L"GetRetDimsOfPart, could not get doc%d",iDoc) ; return ; }
// Try to convert from general doc to IDW drawing doc pIDWDoc = pDoc ; if (pIDWDoc != nullptr) { // The conversion worked so this is an IDW document,our first... TRACE (L"Doc %d is an IDW",iDoc) ; break ; } }
if (pIDWDoc == nullptr) { TRACE (L"Could not find an IDW") ; return ; }
// Find the sheets of the drawing document...
124 Autodesk Inventor Programming in C++ by Owen Ransen
(C) 2021 Owen F Ransen
CComPtr<Sheets> pSheets ; hRes = pIDWDoc->get_Sheets(&pSheets) ; if (FAILED(hRes) || (pSheets == nullptr)) { ShowCOMError (hRes,L"GetRetDimsOfPart, could not getsheets of drawing document."); return ; }
// Get the (assumed) single sheet inside the IDW. Rememberthe first object // in a COM list had index 1... CComPtr<Sheet> pSheet ; hRes = pSheets->get_Item (CComVariant(1),&pSheet) ; if (FAILED(hRes) || (pSheet == nullptr)) { ShowCOMError (hRes,L"GetRetDimsOfPart, could not get 1stsheet of drawing."); return ; }
// Get all the views of the sheet... CComPtr<DrawingViews> pViews ; hRes = pSheet->get_DrawingViews (&pViews) ; if (FAILED(hRes) || (pViews == nullptr)) { ShowCOMError (hRes,L"GetRetDimsOfPart, get_DrawingViewsfailed."); return ; }
// Get the first view, you're assuming that there is one... CComPtr<DrawingView> pThisView ; hRes = pViews->get_Item(1,&pThisView) ; if (FAILED(hRes) || (pThisView == nullptr)) { ShowCOMError (hRes,L"GetRetDimsOfPart, get_Item(1) forview failed."); return ; }
CComPtr<DrawingDimensions> pDwgDimensions ; pSheet->get_DrawingDimensions (&pDwgDimensions) ;
CComPtr<GeneralDimensions> pGenDims ; pDwgDimensions->get_GeneralDimensions (&pGenDims) ;
CComPtr<ObjectCollection> pAllRetCollection ; hRes = pGenDims->GetRetrievableDimensions(pThisView,gkvarEmpty,&pAllRetCollection) ; if (FAILED (hRes)) { TRACE"Could not get ret dims") ; return ;
} else { WalertBoxA ("Got RetrievableDims ok, there are%d.",pAllRetCollection->Count) ;
125Programming Inventor in C++
(C) 2021 Owen F Ransen
}
const long ikNumRetDims = pAllRetCollection->Count ;
// Change this to 0 or 1#define ALL_DIMENSIONS 0
#if ALL_DIMENSIONS /* * Make the dimensions actually appear in the IDW drawingdocument */ CComPtr<GeneralDimensionsEnumerator> pGenDimsEnum1; hRes = pGenDims->Retrieve(pThisView, CComVariant(pAllRetCollection),//This tells it to get all dimensions gkvarEmpty, &pGenDimsEnum1);#else
// Do this so you can create object collections... CComPtr<TransientObjects> pTransObjs =GetTransientObjectsPtr() ;
// Create an initially empty object collection... CComPtr<ObjectCollection> pJustOneDim ; hRes = pTransObjs->CreateObjectCollection(gkvarEmpty,&pJustOneDim) ;
// Get only the first dimension from the retrievabledimensions... IDispatchPtr pFirstDim; hRes = pAllRetCollection->get_Item(_variant_t(1),&pFirstDim);
// Add it into the collection of "just one dimension"... pJustOneDim->Add (pFirstDim) ;
// Add the single dimension into the drawing... CComPtr<GeneralDimensionsEnumerator> pGenDimsEnum1; hRes = pGenDims->Retrieve(pThisView, CComVariant(pJustOneDim), // Thistell it to get just the first dimension &pGenDimsEnum1);
#endif}
Listing the DimensionConstraints...
126 Autodesk Inventor Programming in C++ by Owen Ransen
(C) 2021 Owen F Ransen
12.60 DrawingDimensions vs GeneralDimensions
The lists they give are often the same. DrawingDimensions is at ahigher level than GeneralDimensions, and GeneralDimensions letsyou get hold of the RetrievableDimensions.
// This will get all the dimensions currently visible in the sheet as wellas giving // you a way of getting the general dimensions and hence the retrievabledimensions... CComPtr<DrawingDimensions> pDimensions = nullptr ; hRes = pSheet->get_DrawingDimensions (&pDimensions) ;
// The general dimensions gives you a way of getting at the retrievabledimensions.... CComPtr<GeneralDimensions> pGenDimensions = nullptr ; hRes = pDimensions->get_GeneralDimensions (&pGenDimensions) ;
// NOW you can get the retrievable dimensions CComPtr<ObjectCollection> pObjColl; hRes = pGenDimensions->GetRetrievableDimensions(pThisView, CComVariant(),&pObjColl);
Both GeneralDimensions and DrawingDimensions will also list thedimension objects in the sheet:
for (long i = 1; i <= pGenDimensions->Count; i++) { CComPtr<GeneralDimension> pGenDim; pGenDimensions->get_Item(i, &pGenDim);
CComPtr <DimensionText> pDimText; pGenDim->get_Text(&pDimText);
CComBSTR DimText; pDimText->get_Text(&DimText);
gLogger.Printf(ekLogMsg, L"GeneralDimension Type is <%d> <%s> Text is<%s>", pGenDim->Type, GetObjTypeDesc(pGenDim->Type), CString(DimText));
127Programming Inventor in C++
(C) 2021 Owen F Ransen
}
for (long i = 1; i <= pDimensions->Count; i++) { CComPtr<DrawingDimension> pDwgDim; pDimensions->get_Item(i, &pDwgDim);
double ModelValue; pDwgDim->get_ModelValue(&ModelValue);
CComPtr <DimensionText> pDimText; pDwgDim->get_Text(&pDimText);
CComBSTR DimText; pDimText->get_Text(&DimText);
gLogger.Printf(ekLogMsg, L"DrawingDim Type is <%d> <%s> Text is <%s>ModelValue=%.2f", pDwgDim->Type, GetObjTypeDesc(pDwgDim->Type), CString(DimText),ModelValue); }
Model value is the actual number of the value, whereas the Text iswhat appears in the drawing.
12.61 Negative Dimensions
Dimensions can only be positive, so if you want a negative dimension(as a way of positioning a hole to the left or right of another feature forexample) you need to put a point at one extreme and then use a UserParameter. This example should make it clear:
128 Autodesk Inventor Programming in C++ by Owen Ransen
(C) 2021 Owen F Ransen
When R1Scosta is 0 the circle is on the Z axis.
12.62 Show a dimension programatically
This function will try to show a list of dimensions, when eachdimension is based on a parameter.
And the definition is this (no error checking):
void ShowNamedRetDimsInView (const CString& kcsViewName, const CStringList& kcsParamNames, CComQIPtr<DrawingDocument>& pIDWDoc){ // Find the sheets of the drawing document... CComPtr<Sheets> pSheets = nullptr ; HRESULT hRes = pIDWDoc->get_Sheets(&pSheets) ;
// Get the (assumed) single sheet inside the IDW. Remember the firstobject // in a COM list had index 1...
129Programming Inventor in C++
(C) 2021 Owen F Ransen
CComPtr<Sheet> pSheet = nullptr ; hRes = pSheets->get_Item (CComVariant(1),&pSheet) ;
CComPtr<DrawingView> pThisView = nullptr ; const bool kbViewOk = FindDrawingViewInSheetByName (pThisView,pSheet,kcsViewName) ; if (!kbViewOk) { gLogger.Printf (ekErrMsg, L"SNRDIV2, could not find view <%s>.", kcsViewName); return ; }
CComPtr<DrawingDimensions> pDimensions = nullptr ; hRes = pSheet->get_DrawingDimensions (&pDimensions) ;
// The general dimensions gives you a way of getting at the retrievabledimensions.... CComPtr<GeneralDimensions> pGenDimensions = nullptr ; hRes = pDimensions->get_GeneralDimensions (&pGenDimensions) ;
// The Arrange function requires an object collection of dimensions toarrange... CComPtr<TransientObjects> pTransientObjects = GetTransientObjectsPtr() ; CComPtr<ObjectCollection> pObjCollection = nullptr ; hRes = pTransientObjects->CreateObjectCollection (gkvarEmpty,&pObjCollection) ; if (FAILED(hRes)) { ShowCOMError (hRes,L"CreateObjectCollection failed "); return; }
// Retrieve *all* retrievable dimensions. This will make all thedimensions appear in the drawing... CComPtr<GeneralDimensionsEnumerator> pGenDimsEnum; hRes = pGenDimensions->Retrieve(pThisView, CComVariant(), &pGenDimsEnum);
long nTotalDims=0; hRes = pGenDimsEnum->get_Count(&nTotalDims);
// Go over all the dimensions, erasing those not in my list... for(int nDim = 1; nDim <= nTotalDims; nDim++) { CComPtr<GeneralDimension> pGenDim; hRes = pGenDimsEnum->get_Item(_variant_t(nDim), &pGenDim);
CComPtr <DimensionText> pDimText; pGenDim->get_Text(&pDimText);
CComBSTR DimText; pDimText->get_Text(&DimText);
CComBSTR paramName; IDispatchPtr pGenDimIDisp;
130 Autodesk Inventor Programming in C++ by Owen Ransen
(C) 2021 Owen F Ransen
hRes = pGenDim->get_RetrievedFrom(&pGenDimIDisp);
CComQIPtr<FeatureDimension> pFeatureDim = CComQIPtr<FeatureDimension>(pGenDimIDisp); if(pFeatureDim != NULL) { CComPtr<Parameter> pParam; hRes = pFeatureDim->get_Parameter(&pParam); hRes = pParam->get_Name(¶mName); }
CComQIPtr<DimensionConstraint> pDimConstraint = CComQIPtr<DimensionConstraint>(pGenDimIDisp); if(pDimConstraint != NULL) { CComPtr<Parameter> pParam; hRes = pDimConstraint->get_Parameter(&pParam); hRes = pParam->get_Name(¶mName); }
CComQIPtr<FeatureDimensionProxy> pFeatureDimProxy = CComQIPtr<FeatureDimensionProxy>(pGenDimIDisp); if(pFeatureDimProxy != NULL) { CComPtr<Parameter> pParam; hRes = pFeatureDimProxy->get_Parameter(&pParam); hRes = pParam->get_Name(¶mName); }
/* * We will delete this dimension if it is NOT in the list * of dimensions we want. */ bool bDelete = true ; for (INT_PTR iParam = 0 ; iParam < kcsParamNames.GetCount ();iParam++) { const POSITION Pos = kcsParamNames.FindIndex (iParam) ; const CString kcsListed = kcsParamNames.GetAt (Pos) ; if (wcscmp (kcsListed.GetString(),paramName) == 0) { // This parameter, paramName, is in the list, so I don'tdelete it bDelete = false ; break ; } }
if (bDelete) { // This parameter is not one we want to retain... pGenDim->Delete();
} else { // Add to the collection of dimensions to be arranged later... pObjCollection->Add(pGenDim); }
131Programming Inventor in C++
(C) 2021 Owen F Ransen
}
if (pObjCollection->Count > 0) { pDimensions->Arrange(pObjCollection); }}
You can call the function in this way:
CStringList csNames; csNames.AddHead(L"d147"); // This corresponds to the length of thecollettore csNames.AddHead(L"Extra"); csNames.AddHead(L"Diameter7"); ShowNamedRetDimsInView (L"Front",csNames,pDrawingDoc) ;
12.63 Dimensions in a drawing sheet
Here's how to count the number of dimensions in a drawings sheet:
CComPtr<DrawingViews> pViews = nullptr ; hRes = pSheet->get_DrawingViews (&pViews) ;
{ CComPtr<DrawingDimensions> pDimensions = nullptr ; hRes = pSheet->get_DrawingDimensions (&pDimensions) ; if (FAILED(hRes)) { ShowCOMError (hRes,L"pSheet->get_DrawingDimensionsfailed "); }
long lNumDims; hRes = pDimensions->get_Count(&lNumDims); if (FAILED(hRes)) { ShowCOMError (hRes,L"pDimensions->get_Count failed "); }
WalertBoxA ("This has %d dimensions",lNumDims) ; }
See also retrievable dimensions.
132 Autodesk Inventor Programming in C++ by Owen Ransen
(C) 2021 Owen F Ransen
12.64 Plane object, getting its geometry
Here is how to get it from a proxy inside an assembly, but you canuse a similar function for a real WorkPlane.
// This will get you the point and the normal which define the workplanevoid GetWorkPlaneProxyData(CVec& vecRoot, CVec& vecNormal, CComPtr<WorkPlaneProxy>& pWorkPlaneProxy){ double RootCoords[3]; SAFEARRAY* pRootArray = CreateSafeDoubleArray(3, RootCoords) ;
double NormalCoords[3]; SAFEARRAY* pNormArray = CreateSafeDoubleArray(3, NormalCoords) ;
pWorkPlaneProxy->Plane->GetPlaneData(&pRootArray,&pNormArray);
for (LONG i = XI ; i <= ZI; i++) { LONG rgIndex = i; double Root = 0; SafeArrayGetElement(pRootArray, &rgIndex, &Root); vecRoot.SetVal(i, Root);
double Norm = 0; SafeArrayGetElement(pNormArray, &rgIndex, &Norm); vecNormal.SetVal(i, Norm); }
SafeArrayDestroy(pRootArray); SafeArrayDestroy(pNormArray);}
133Programming Inventor in C++
(C) 2021 Owen F Ransen
12.65 Open a part from a view
Here is a fragment to show you how:
CComPtr<DocumentDescriptor> pDocDesc ; pView->get_ReferencedDocumentDescriptor (&pDocDesc) ;
// Still finding out the part which this is a view of... CComPtr<Document> pReffedDoc ; pDocDesc->get_ReferencedDocument ((IDispatch**)&pReffedDoc) ;
if (kAssemblyDocumentObject != pReffedDoc->DocumentType) { WalertBoxW (L"The referenced document is not an assemblu part") ; return ; }
// Convert the general referenced doc into a part doc... CComQIPtr<AssemblyDocument> pAsmDoc = pReffedDoc ;
// Get assembly component definition CComPtr<AssemblyComponentDefinition> pAssemblyCompDef ; hRes = pAsmDoc->get_ComponentDefinition(&pAssemblyCompDef); if (FAILED(hRes) || (pAssemblyCompDef == nullptr)){ ShowCOMError(hRes,L"GetComponentOccurrenceByName, get_ComponentDefinition failed "); return ; }
CComPtr<ComponentOccurrences> pOccurrencesList=nullptr; hRes = pAssemblyCompDef->get_Occurrences (&pOccurrencesList) ; if (FAILED(hRes) || (pOccurrencesList==nullptr)) { ShowCOMError (hRes,L"get_Occurrences failed") ; return ; }
CComPtr<ComponentOccurrence> pThisCompOcc ;hRes = pOccurrencesList->get_Item(1, &pThisCompOcc);
if (FAILED(hRes) || (pThisCompOcc == nullptr)){ ShowCOMError(hRes,L"GetComponentOccurrenceByName, get_Item failed "); return ; }
// Now find out the part which this is a view of... CComPtr<DocumentDescriptor> pDocDesc2 ; pThisCompOcc->get_ReferencedDocumentDescriptor (&pDocDesc2) ;
CComBSTR bstrFullDocName ; pDocDesc2->get_FullDocumentName (&bstrFullDocName) ;
134 Autodesk Inventor Programming in C++ by Owen Ransen
(C) 2021 Owen F Ransen
WalertBoxW (L"Referenced doc = %s",bstrFullDocName) ;
CComPtr<PartComponentDefinition> pPartCompDef ; CComPtr<PartDocument> pPartDoc ; CComPtr<Application> pInvApp = theApp.GetInvAppPtr () ;
hRes = OpenPart (pPartCompDef, pPartDoc, CString(bstrFullDocName), pInvApp) ;
.
12.66 getType and ObjectTypeEnum
You can use GetType (or get_Type()) to see what sort of object youhave.
For example:
CComPtr<ModelParameter> pModelParam ; ... other stuff
// Two ways of getting the object type... TRACE (L"pModelParam->GetType()=%d\n",pModelParam->GetType());
ObjectTypeEnum ObjType ; pModelParam->get_Type (&ObjType) ;
TRACE (L"pModelParam->get_Type()=%d\n",ObjType) ;
If you have initialised pModelParam properly it will return 50348544 (kModelParameterObject).
Other common values are:
kComponentOccurrenceObject = 67113776, kAssemblyDocumentObject = 12291 kPartComponentDefinitionObject = 83886592, kFeaturePatternElementObject = 83923968, kObjectCollectionObject = 2130706443, kWorkPlaneObject = 83887616, kWorkPointObject = 83893504, kWorkPointProxyObject = 83893664,
135Programming Inventor in C++
(C) 2021 Owen F Ransen
kTwoPointDistanceDimConstraintProxyObject = 83905904 kDiameterDimConstraintProxyObject = 83906672
This example shows that get_Type will give you a high leveldescription, it does not tell you which sort of model parameter it is(double, count, etc). For that you need the ParameterTypeEnum.
The full set of values can be found in rxinventor.tlh, which will besomewhere like:
C:\Users\Public\Documents\Autodesk\Inventor 2017\SDK\DeveloperTools\Samples\VC++\AddIns\SimpleAddIn\x64\Debug\rxinventor.tlh
or in the API help file.
You may find this function useful, adding more cases as youneed/find them:
CString GetObjTypeDesc (const ObjectTypeEnum eObjType)/*Returns a string version of the object type.*/{ switch (eObjType) { case kWorkAxisObject: return CString ("kWorkAxisObject") ;
case kWorkPointObject: return CString ("kWorkPointObject") ;
case kWorkPlaneObject: return CString ("kWorkPlaneObject") ;
case kTwoPointDistanceDimConstraintProxyObject: return CString ("kTwoPointDistanceDimConstraintProxyObject") ;
case kDiameterDimConstraintProxyObject: return CString ("kDiameterDimConstraintProxyObject") ;
case kTwoLineAngleDimConstraintProxyObject: return CString ("kTwoLineAngleDimConstraintProxyObject") ;
case kTangentDistanceDimConstraintProxyObject: return CString ("kTangentDistanceDimConstraintProxyObject") ;
case kOffsetDimConstraintProxyObject: return CString ("kOffsetDimConstraintProxyObject") ;
case kRadiusDimConstraintProxyObject: return CString ("kRadiusDimConstraintProxyObject") ;
136 Autodesk Inventor Programming in C++ by Owen Ransen
(C) 2021 Owen F Ransen
case kDrawingViewObject: return CString ("kDrawingViewObject") ;
case kMateiMateDefinitionObject: return CString ("kMateiMateDefinitionObject") ;
case kiMateDefinitionObject : return CString("kiMateDefinitionObject");
case kAngleiMateDefinitionObject: return CString("");
case kFlushiMateDefinitionObject: return CString("kFlushiMateDefinitionObject");
case kInsertiMateDefinitionObject: return CString("kInsertiMateDefinitionObject");
case kTangentiMateDefinitionObject: return CString("kTangentiMateDefinitionObject");
case kCompositeiMateDefinitionObject: return CString("kCompositeiMateDefinitionObject");
case kRotateRotateiMateDefinitionObject: return CString("kRotateRotateiMateDefinitionObject");
case kRotateTranslateiMateDefinitionObject: return CString("kRotateTranslateiMateDefinitionObject");
case kiMateResultsObject: return CString("kiMateResultsObject");
case kiMateResultObject: return CString("kiMateResultObject");
case kLinearGeneralDimensionObject: return CString("kLinearGeneralDimensionObject"); case kDiameterGeneralDimensionObject: return CString("kDiameterGeneralDimensionObject");
default: { CString csUnknown ; csUnknown.Format (L"Unknown ObjTypeEnum %d",eObjType) ; return csUnknown ; } }}
137Programming Inventor in C++
(C) 2021 Owen F Ransen
12.67 Listing types of dimensions in a view
This code fragment shows you how to get hold of theDimensionConstraints:
CComPtr<ObjectCollection> pAllRetCollection ; hRes = pGenDims->GetRetrievableDimensions(pThisView,gkvarEmpty,&pAllRetCollection) ; if (FAILED (hRes)) { TRACE"Could not get ret dims") ; return ;
} else { WalertBoxA ("Got RetrievableDims ok, there are%d.",pAllRetCollection->Count) ; }
const long ikNumRetDims = pAllRetCollection->Count ;
for (long iDim = 1 ; iDim <= ikNumRetDims ; iDim++) { IDispatchPtr pNthDim; hRes = pAllRetCollection->get_Item(_variant_t(iDim),&pNthDim);
CComPtr<DimensionConstraint> pDimConstraint ; hRes = pNthDim->QueryInterface(__uuidof(DimensionConstraint), (void **)&pDimConstraint);
if (FAILED (hRes)) { TRACE (L"Could not query interface of dim %d of%d\n",iDim,ikNumRetDims) ;
} else { ObjectTypeEnum eType = pDimConstraint->GetType() ; TRACE (L" dim %d is a %d %s\n",iDim,eType,GetObjTypeDesc(eType)) ; CComPtr<Parameter> pThisParam ; hRes = pDimConstraint->get_Parameter (&pThisParam) ; if (FAILED (hRes)) { TRACE (L"Could not get parameter of dim %d of%d\n",iDim,ikNumRetDims) ;
} else { CComBSTR bstrParamName ; pThisParam->get_Name (&bstrParamName) ; TRACE (L"Param of dim %d is%s\n",iDim,bstrParamName) ; }
138 Autodesk Inventor Programming in C++ by Owen Ransen
(C) 2021 Owen F Ransen
}
pNthDim = nullptr ; // free the IDispatch pointer }
It also shows you how to get an item as an IDispatchPtr and turn itinto a DimensionConstraint (for example), and how to get the name ofthe parameter which controls the dimension.
12.68 Getting the version of Inventor programatically
Here is the code to do it:
CComPtr<Application> pInvApp = ...
CComBSTR bstrVersion ; pInvApp->SoftwareVersion->get_DisplayName (&bstrVersion) ; TRACE (L"Software version DisplayName is <%s>\n",bstrVersion) ;
pInvApp->SoftwareVersion->get_DisplayVersion (&bstrVersion) ; TRACE (L"Software version DisplayVersion is <%s>\n",bstrVersion) ;
And the output in your debug window will look something like this:
Software version DisplayName is <2013 (Build 170138000, 138)>Software version DisplayVersion is <2013>
Apart from DisplayName and DisplayVersion there are other functionslike get_Major and get_Minor. For example:
long iMajorVer ; pInvApp->SoftwareVersion->get_Major (&iMajorVer) ;
long iMinorVer ; pInvApp->SoftwareVersion->get_Minor (&iMinorVer) ;
TRACE (L"Software version Major=%d, Minor=%d\n",iMajorVer,iMinorVer) ;
with this result:
Software version Major=17, Minor=0
139Programming Inventor in C++
(C) 2021 Owen F Ransen
But I don't find numbers as helpful as the display strings.
12.69 QueryInterface and Release Etc
If possible use CComQIPtr. If you insist you can read the following...
There is some confusion in this question's answers about whatQueryInterface actually does. It simply retrieves pointers to thesupported interfaces on an object and increments the reference counton that object. It doesn't create a new object for each interface that itimplements.
For example if you have an object which implements 2 interfaces,then the call would simply cast that object as each of the interfaceand increment a variable which is used as the reference count.
QueryInterface allows the caller to retrieve references to differentinterfaces the component implements. It is similar to dynamic_cast<>in C++. Specifically, it is used to obtain a pointer to another interface,given a GUID that uniquely identifies that interface (commonly knownas an interface ID, or IID). If the COM object does not implement thatinterface, an E_NOINTERFACE error is returned instead.
COM object gives you some pointers to certain functions that you cancall to manipulate the object.
COM object is basically a C++ class. A C++ class is just a struct thatalways starts with a pointer to its VTable (an array of functionpointers). And the first three pointers in the VTable will always benamed QueryInterface, AddRef, and Release. What additionalfunctions may be in its VTable, and what the name of their pointersare, depends upon what type of object it is.
This is another important rule of COM. If you get hold of a COMobject created by someone else, you must call its Release functionwhen you're done with it.
CComQIPtr is a CComPtr with a QueryInterface inside it, apparently.
140 Autodesk Inventor Programming in C++ by Owen Ransen
(C) 2021 Owen F Ransen
12.70 CComQIPtr is better than QueryInterface
Instead of doing a QueryInterface where you have to worry aboutRelease etc., you can sometimes use a CComQIPtr, like this:
CComQIPtr<DimensionConstraint> pDimConstraint ; // It is null now (cannot be initialised to NULL) for (long iDim = 1 ; iDim <= ikNumRetDims ; iDim++) {
TRACE (L"Looking at dim %d of %d\n",iDim,ikNumRetDims) ;
// Look at the nth dimension in the collection... IDispatchPtr pNthDim; hRes = pAllRetCollection->get_Item(_variant_t(iDim), &pNthDim); if (FAILED (hRes)) { ShowCOMError (hRes,L"ShowNamedRetDimInView Could not get_Item %d",iDim) ; return ; }
pDimConstraint = pNthDim ; // This can be tested for NULL
if (pDimConstraint != NULL) { // We have a DimensionConstraint, what is the name of the model parameter?
CComPtr/CComQIPtr perform automatic reference counting for you (forexample, they call Release on the interface attached to them, whenthe smart-pointer variable goes out of scope).
And CComQIPtr is null when you first create it. See comment on firstline of the code above.
12.71 How to get iPart factory parent from child member
In C++ follow this example:
// This will give you"C:\Users\Owen\Documents\Inventor\Tubi_Rame_12-7_Liscio_Sp0,75.IPT" wchar_t* pszFullName = LPWSTR (pTroncCompDef->iPartMember->ReferencedDocumentDescriptor->FullDocumentName); if (pszFullName == nullptr) { return false; }
// Now get "Tubi_Rame_12-7_Liscio_Sp0,75.IPT"
141Programming Inventor in C++
(C) 2021 Owen F Ransen
CString csIPartFileName(pszFullName); StripPath(csIPartFileName);
// Now load with "Tubi_Rame_12-7_Liscio_Sp0,75.IPT" LoadTronchettiFile(csIPartFileName);
if (csIPartFileName.GetLength() < NUM_SAP_CHARS) { return false; }
// Get the member name "30089191.IPT" const CString kcsPartName = GetPartName(pTroncCompDef);
// Remove the IPT to get "30089191" const CString kcsTroncSapCode = kcsPartName.Mid(0, NUM_SAP_CHARS);
// Use "30089191" to find the details return GetTroncDetailsByCode(Details,kcsTroncSapCode);
In VB it would be like this:
Public Sub main()
Dim a As Application Set a = ThisApplication
Dim b As PartDocument Set b = a.ActiveDocument
a.Documents.Open (b.ComponentDefinition.iPartMember.ReferencedDocumentDescriptor.FullDocumentName)
End Sub
I need to translate this into C++.
12.72 Counting the number of documents open in Inventor
Get a pointer to the Inventor application, then use this code:
// Get the list of Documents CComPtr<Documents> pDocs; HRESULT hr = pInvApp->get_Documents(&pDocs); if (FAILED(hr)) { return ReturnAndShowCOMError (hr,L"CreateNewPartDoc, get document list failed\n") ; } const long ikNumDocs = pDocs->GetCount() ; TRACE (L"There are %d documents open in Inventor\n",ikNumDocs) ;
142 Autodesk Inventor Programming in C++ by Owen Ransen
(C) 2021 Owen F Ransen
Here is a function which encloses the above code:
size_t GetNumDocummentsOpenInInventor(){ CComPtr<Application> pInvApp = theApp.GetInvAppPtr() ; if (pInvApp == nullptr) { return 0 ; }
// Get the list of documents... CComPtr<Documents> pDocs ; HRESULT hRes = pInvApp->get_Documents (&pDocs) ; if (FAILED(hRes) || (pDocs == nullptr)) { ShowCOMError(hRes,L"GNDOII,get_Documents failed "); return 0 ; }
return pDocs->Count ;}
You can loop over the open dopcuments in Inventor like this:
// Get the pointer to the Inventor application... CComPtr<Application> pInvApp = ...
CComPtr<Documents> pDocs ; HRESULT hRes = pInvApp->get_Documents (&pDocs) ; if (FAILED(hRes) || (pDocs == nullptr)) { TRACE (L"RunTest,get_Documents failed "); return ; }
const long ikNumDocs = pDocs->GetCount() ;
TRACE ("There are %d documents open\n",ikNumDocs) ;
for (int iDoc = 1 ; iDoc <= ikNumDocs ; iDoc++) { CComPtr<Document> pDocument; hRes = pDocs->get_Item(iDoc,&pDocument) ; if (FAILED(hRes) || (pDocument == nullptr)) { TRACE (L"Could not get document number %d",iDoc); return ; } TRACE ("Got document %d of type %d %s\n", iDoc,
143Programming Inventor in C++
(C) 2021 Owen F Ransen
pDocument->DocumentType, GetInventorDocTypeDesc(pDocument->DocumentType)); }
You'll get a listing in the debug window something like this:
Got document 1 of type 12291 Assembly DocumentGot document 2 of type 12290 Part DocumentGot document 3 of type 12290 Part DocumentGot document 4 of type 12290 Part DocumentGot document 5 of type 12290 Part DocumentGot document 6 of type 12290 Part DocumentGot document 7 of type 12290 Part DocumentGot document 8 of type 12290 Part DocumentGot document 9 of type 12292 Drawing DocumentGot document 10 of type 12290 Part Document
12.73 CustomTables in Sheets and Drawings
This example C++ code shows how to create a custom table in anIDW Inventor drawing:
void CreateExampleTable (CComPtr<Sheet>& pSheet){ wchar_t* ColNames[128] = {L"Column One",L"Column Two",L"Column Three"};
// These contents are after the title row and the header row const int ikNumCols = 3 ; const int ikNumRows = 5 ; // 7 with header and column titles
SAFEARRAY* pstrColumns = CreateSafeStringArray(ikNumCols, ColNames);
CComPtr<CustomTables> pCustomTables ; pSheet->get_CustomTables (&pCustomTables) ;
// This is top left of the table. Sheet origin is bottom left. // In Europe this coordinate system is usually cm in a sheet CComPtr<Point2d> ptTable; // Create a 2d point GetTransGeomPtr()->CreatePoint2d(10.0,10.0,&ptTable);
CComVariant varEmpty ; CComPtr<CustomTable> pCustomTable ; pCustomTables->Add (CComBSTR(L"HOLES"),ptTable,ikNumCols,ikNumRows,&pstrColumns, varEmpty, // the contents will be added later
144 Autodesk Inventor Programming in C++ by Owen Ransen
(C) 2021 Owen F Ransen
varEmpty, // use the default widths varEmpty, // use the default heights varEmpty, // no more info &pCustomTable) ; // table returned
/* * Here we add contents by using put_Value in every cell */ for (UINT iRow = 1 ; iRow <= ikNumRows ; iRow++) { // Get the row where we want to add data... CComPtr<Row> pRow ; pCustomTable->Rows->get_Item (long(iRow),&pRow) ; for (UINT iCol = 1 ; iCol <= ikNumCols ; iCol++) { // Get the column of the row where we want to add data... CComPtr<Cell> pCell ; pRow->get_Item (CComVariant(iCol),&pCell) ;
// Demo example text... wchar_t szCellContents[_MAX_PATH] ; swprintf_s (szCellContents,L"R%d C%d",iRow,iCol) ;
// Put the data in the cell... pCell->put_Value (CComBSTR (szCellContents)) ; } }
SafeArrayDestroy (pstrColumns) ;}
The resulting table looks like this:
145Programming Inventor in C++
(C) 2021 Owen F Ransen
The code does not include error checking, which you should add inyour own versions.
If you want to specify column widths you need to pass in a VARIANTwhich is an array of doubles, see WidthsVariant below:
VARIANT WidthsVariant ; double ColWidths[5] = {2.5,3.5,4.5,6.5,2.5} ; CreateDoubleVariantArray (WidthsVariant,ColWidths,5) ;
CComVariant varEmpty ; CComPtr<CustomTable> pCustomTable ; HRESULT hRes = pCustomTables->Add (CComBSTR(L"Special Data"), ptTable, ikNumCols,ikNumRows,&pstrColumns, varEmpty, // the contents will be added later WidthsVariant, // widths of columns varEmpty, // use the default heights varEmpty, // no more info &pCustomTable) ; // table returned
Positioning objects in a Sheet.
146 Autodesk Inventor Programming in C++ by Owen Ransen
(C) 2021 Owen F Ransen
12.74 Positioning objects in a Sheet.
When you position text and tables in a sheet the origin of the sheet isbottom left. Tables are positioned by their top left corner, presumablyto let the rows grow downwards without having to redefine theposition.
As far as I can tell when metric, centimeters are used. Orientation ofthe sheet.
12.75 New line within table cells
To add a new line within a cell of a custom table you should use \r\n.
for (UINT i = 0 ; i <= iSoFar ; i++) {
147Programming Inventor in C++
(C) 2021 Owen F Ransen
CString csPasso ; csPasso.Format (L"%dx%d\r\n",Counts[i], int(RoundNumber(Passi[i],0))) ;
if (i != iSoFar) { // Separator needed.... csPasso += CString ("-") ; }
csPassi += csPasso ; }
12.76 CreateDoubleVariantArray
This function is useful for creating VARIANTs which specify thewidths of the columns in a CustomTable...
void CreateDoubleVariantArray (VARIANT& v, const double* constpValues, const UINT ikNumValues)/*Some functions, like adding a custom table into a sheet, requireVARIANTs which arearrays of doubles. This function, given an array of doublesinitialises the variant v.*/{ v.vt = VT_ARRAY | VT_R8; SAFEARRAYBOUND sab[1]; sab[0].lLbound = 0; sab[0].cElements = ikNumValues ; v.parray = SafeArrayCreate(VT_R8, 1, sab);
// Fill with some values... for(int i=0; i<ikNumValues; i++) { long indices[] = {i}; SafeArrayPutElement(v.parray, indices, (void*)&(pValues[i])); }}
148 Autodesk Inventor Programming in C++ by Owen Ransen
(C) 2021 Owen F Ransen
12.77 Create a drawing file (IDW or DWG)
This code (with error checking omitted) creates a new empty drawingfile:
// Get the pointer to the Inventor application... CComPtr<Application> pInvApp = ...
// Get IDW drawing template file CComBSTR strTemplateFilename; CComPtr<FileManager> pFileManager ; HRESULT hRes = pInvApp->get_FileManager(&pFileManager); hRes = pFileManager->GetTemplateFile(kDrawingDocumentObject, // i.e. an IDW or DWG kDefaultSystemOfMeasure, kDefault_DraftingStandard, CComVariant(), // Empty and unused &strTemplateFilename);
CComPtr<Documents> pDocuments; pInvApp->get_Documents (&pDocuments) ;
// create a new drawing from the standard template CComPtr<Document> pDocument ; hRes = pDocuments->Add (kDrawingDocumentObject, strTemplateFilename, VARIANT_TRUE, // Create Visible &pDocument);
// Convert from the "general document" type into the "drawing document" type... CComQIPtr<DrawingDocument> pDrawingDoc ; pDrawingDoc = pDocument ;
When you do copy/paste of this code for other document types,remember to change the enumerator of the types in both calls.
Also note that the document you create will already have one sheet init, you normally do not need to add any more. It is more likely that youwant to add views to the sheet.
See also creating an assembly.
149Programming Inventor in C++
(C) 2021 Owen F Ransen
12.78 How to add views to a drawing sheet (Inventor API)
If you have a new or exisiting drawing it is likely that you want to addviews of the 3D object into the sheet. Here is a commentedcode fragment which shows you to do it (error checking removed).Note also that we open the assembly invisibly so the user does nothave to wait for the display of the assembly.
// Choose the IDW drawing template file CComBSTR strTemplateFilename; strTemplateFilename = L"C:\\Users\\Public\\Documents\\Autodesk\\Inventor 2014\\Templates\\Ransen.idw" ;
// Get the list of documents so we can add a new one to it (an IDW) CComPtr<Documents> pDocuments; pInvApp->get_Documents (&pDocuments) ;
// create a new IDW drawing from the selected template CComPtr<Document> pDocument ; HRESULT hRes = pDocuments->Add(kDrawingDocumentObject, strTemplateFilename, VARIANT_TRUE, // true = create the document visible &pDocument);
// Convert from the "general document" type into the "drawing document" type... CComQIPtr<DrawingDocument> pDrawingDoc ; pDrawingDoc = pDocument ;
// Get the sheets in the drawing document. Since this IDW has only just been // created there will be a single sheet CComPtr<Sheets> pSheets ; hRes = pDrawingDoc->get_Sheets(&pSheets) ;
// Get the single sheet inside the IDW. Remember the first object // in a COM list had index 1... CComPtr<Sheet> pSheet ; hRes = pSheets->get_Item (CComVariant(1),&pSheet) ;
// Just for fun, get some data about the sheet... double SheetHeight,SheetWidth ; CComBSTR bstrSheetName ; pSheet->get_Name (&bstrSheetName) ; pSheet->get_Width(&SheetWidth) ; pSheet->get_Height(&SheetHeight) ;
TRACE (L"The first sheet is called <%s> and is %.1f %.1f\n", bstrSheetName,SheetWidth,SheetHeight) ;
// Now, we are going to add 2 views to the sheet, so get the list of views
150 Autodesk Inventor Programming in C++ by Owen Ransen
(C) 2021 Owen F Ransen
// Since this is a new drawing there will be no views yet, but we need // the list to add a view... CComPtr<DrawingViews> pViews ; hRes = pSheet->get_DrawingViews (&pViews) ;
// Create two points (using the transient geometry machine) which will // position the views in the sheet... CComPtr<TransientGeometry> pTrGeom = GetTransGeomPtr(); CComPtr<Point2d> pPt1; CComPtr<Point2d> pPt2; pTrGeom->CreatePoint2d(10.0,10.0,&pPt1); pTrGeom->CreatePoint2d(10.0,30.0,&pPt2);
// Set the view scales that we need. const double kViewScale1 = 0.25 ; const double kViewScale2 = 0.125 ;
// Now get hold of the assembly which we want to show in the view // (We'll open it invisibly) CComBSTR strAssemblyFilename ; strAssemblyFilename = L"C:\\CollMakeV2\\Coll_IPT_IAM\\new test.iam" ;
CComPtr<Document> pDoc ; hRes = pDocuments->Open (strAssemblyFilename, // what to open VARIANT_FALSE, // open it invisible &pDoc) ; // result
// The 6th parameter of AddBaseView requires a proper BSTR type object // else you'll get out of memory errors CComBSTR bstrModelViewName1 = CString (L"PLUTO") ; CComBSTR bstrModelViewName2 = CString (L"NEPTUNE") ;
// Now create our two views, first the base view on which all the others are based... CComVariant varEmpty ; CComPtr<DrawingView> pBaseView1 ; pViews->AddBaseView (pDoc, // what to show pPt1, // center of view kViewScale1, // size, scale, of view kBottomViewOrientation, // from where to view the doc kHiddenLineDrawingViewStyle, // DrawingViewStyleEnum bstrModel, // must be a BSTR varEmpty,varEmpty, // unused in this case &pBaseView1) ; // the created view
CComPtr<DrawingView> pBaseView2 ; pViews->AddBaseView (pDoc, pPt2, kViewScale2, kRightViewOrientation,
151Programming Inventor in C++
(C) 2021 Owen F Ransen
kShadedDrawingViewStyle, // DrawingViewStyleEnum bstrModelViewName2, varEmpty,varEmpty, &pBaseView2) ;
pDoc->Close (VARIANT_TRUE) ; // VARIANT_TRUE = close skipping save, obviously
See here for projected views.
As far as the "where are we looking from" option, these are the mostcommon:
kBottomViewOrientationkBackViewOrientationkCurrentViewOrientationkFrontViewOrientationkLeftViewOrientationkRightViewOrientationkTopViewOrientation
152 Autodesk Inventor Programming in C++ by Owen Ransen
(C) 2021 Owen F Ransen
These correspond in the user interface, to the view cube:
12.79 Names of views programatically
Although AddBaseView has a name parameter, it is not clear to mewhat it means. In fact it never changes the name of the view, to dothat you need to follow this code fragment:
{ CComPtr<DrawingView> pBaseView1 ...
... CComBSTR bstrViewName ; pBaseView1->get_Name (&bstrViewName) ; TRACE (L"Base view name was = <%s>\n",bstrViewName) ;
bstrViewName = L"SideView" ; pBaseView1->put_Name (bstrViewName) ;
pBaseView1->get_Name (&bstrViewName) ; TRACE (L"Base view name now = <%s>\n",bstrViewName) ; }
So just use put_Name to change the name of the view.
153Programming Inventor in C++
(C) 2021 Owen F Ransen
12.80 Creating projected views from base views
This page shows how to put in two base views. If you want to create aprojected view from the first base view, the last part of the codebecomes:
// Now create our two views, a base and a projected view CComVariant varEmpty ; CComPtr<Point2d> pPt1; pTrGeom->CreatePoint2d(10.0,10.0,&pPt1);
// The base view... CComPtr<DrawingView> pBaseView1 ; pViews->AddBaseView (pDoc, // what to show pPt1, // corner of view kViewScale1, // size, scale, of view kBottomViewOrientation, // from where to view the doc kHiddenLineDrawingViewStyle, // DrawingViewStyleEnum L"10-10", // name of created view varEmpty,varEmpty, // unused in this case &pBaseView1) ; // the created view
// In this case we create a projected view which has the base view as // the parent and which is to the right of the parent. Inventor itself will // sort out the projection. (compare pPt1 and pPt2) CComPtr<Point2d> pPt2; pTrGeom->CreatePoint2d(15.0,10.0,&pPt2); CComPtr<DrawingView> pProjectedView ; pViews->AddProjectedView (pBaseView1, // parent view pPt2, // center of projected view kHiddenLineDrawingViewStyle, varEmpty, // empty, so same scale as parent &pProjectedView) ; // resulting projected view
Here is a BaseView and a ProjectedView:
154 Autodesk Inventor Programming in C++ by Owen Ransen
(C) 2021 Owen F Ransen
12.81 Drawing View Styles
With AddProjectedView and AddBaseView you can use theseenumerators (DrawingViewStyleEnum):
kFromBaseDrawingViewStyle = use the base view settingskHiddenLineRemovedDrawingViewStyle = hide hidden lineskHiddenLineDrawingViewStyle = show hiddenl lineskShadedDrawingViewStyle = shaded, no hidden lines visiblekShadedHiddenLineDrawingViewStyle = shaded, show hidden lines
155Programming Inventor in C++
(C) 2021 Owen F Ransen
12.82 Close function for Parts and Assemblies
When you have created a Part or Assembly you may want to close itwith or without saving it. You will Close the assembly or partdocument, for example:
pAssemblyDoc->Close(VARIANT_TRUE) ;
The boolean (and remember to use VARIANT_TRUE orVARIANT_FALSE) tells Inventor whether the part should be savedbefore closing. For example:
pPartDoc->Close(VARIANT_TRUE) ; // "SkipSave" , no saving ,just close the document
pPartDoc->Close(VARIANT_FALSE) ; // Don't "SkipSave", save, andmaybe prompt // the user before closing thedocument
Also note that you can avoid any file saving dialogs by using the"silent" operation. For example:
pInvApp->SilentOperation = VARIANT_TRUE ; // don't show anydialogs, save with default names
// Not you can only do this if the file has not already beensaved pAssemblyDoc->put_FullFileName(CComBSTR(m_csAssemblyFullFileName)) ; // set the name
pAssemblyDoc->Save () ; // do the actual save
pAssemblyDoc->Close(VARIANT_TRUE) ; // close without saving(again)
Remember to switch off SilentOperation at the end of your functions.
12.83 GetInventorDocTypeDesc
Here is a function which will show you a description of the documenttype using the document type enumerator:
typedef struct {
156 Autodesk Inventor Programming in C++ by Owen Ransen
(C) 2021 Owen F Ransen
DocumentTypeEnum eEnum ; const char* const pszDesc ;} DocDesc_t;
const DocDesc_t kDocDescs [] = { {kAssemblyDocumentObject, "Assembly Document"}, {kDesignElementDocumentObject, "Design Element Document"}, {kDrawingDocumentObject, "Drawing Document"}, {kForeignModelDocumentObject, "Foreign Model Document"}, {kNoDocument, "No Document"}, {kPartDocumentObject, "Part Document"}, {kPresentationDocumentObject, "Presentation Document"}, {kSATFileDocumentObject, "SAT File Document"}, {kUnknownDocumentObject, "Unknown Document"}} ;
static const UINT ikNumDocTypeDescs = sizeof (kDocDescs)/sizeof(kDocDescs[0]) ;
const char* const GetInventorDocTypeDesc(const DocumentTypeEnum eDocTypeEnum) { for (UINT i = 0 ; i < ikNumDocTypeDescs ; i++) { if (kDocDescs[i].eEnum == eDocTypeEnum) { return kDocDescs[i].pszDesc ; } }
// This is an error, I handle it recursively... return GetInventorDocTypeDesc(kUnknownDocumentObject) ;}
12.84 Getting the current document of Inventor
It can be done like this:
CComPtr<Application> pApplication;hr = pInvAppUnk->QueryInterface (__uuidof(Application), (void **) &m_pApplication);if (FAILED(hr)) return hr;
CComPtr<Document> pDoc;
hr=pApplication->get_ActiveDocument(&pDoc);
get_ActiveDocument will put NULL in pDoc if there is no documentopen. You have to check that.
You can find out what sort of document it is by looking at the type, forexample:
157Programming Inventor in C++
(C) 2021 Owen F Ransen
if (pDoc->DocumentType==kDrawingDocumentObject)...
by looking at DocumentType. You can use this function to get adescription of the document type
Valid enumerators are:
kAssemblyDocumentObject 12291 Assembly Document. kDesignElementDocumentObject 12294 Design Element Document. kDrawingDocumentObject 12292 Drawing Document. kForeignModelDocumentObject 12295 Foreign Model Document. kNoDocument 12297 No Document. kPartDocumentObject 12290 Part Document. kPresentationDocumentObject 12293 Presentation Document. kSATFileDocumentObject 12296 SAT File Document. kUnknownDocumentObject 12289 Unknown Document.
Apart from looking at the pDoc->DocumentType you can also try to castthe doc into the doc type you are looking for:
// Get the component definition for the document if its a part or assembly.// Return an error for all other document types.CComQIPtr<ComponentDefinition> pCompDef;if (CComQIPtr<PartDocument> pPartDoc = pDoc) // try to cast{ TRACE("This is a part\n"); CComPtr<PartComponentDefinition> pPartCompDef; Result = pPartDoc->get_ComponentDefinition(&pPartCompDef); ...and so on...
} else if (CComQIPtr<AssemblyDocument> pAssemblyDoc = pDoc) { // try to cast TRACE("This is an assembly\n"); CComPtr<AssemblyComponentDefinition> pAssemblyCompDef; Result = pAssemblyDoc->get_ComponentDefinition(&pAssemblyCompDef); ...and so on...
}
There is another way of getting the part document:
// convert generic document to partdocumentCComPtr<PartDocument> pPartDocument;hr = pDocument->QueryInterface(DIID_PartDocument,(void**)&pPartDocument);if (FAILED(hr))
158 Autodesk Inventor Programming in C++ by Owen Ransen
(C) 2021 Owen F Ransen
return ReturnAndShowCOMError (hr,L" get part document failed ") ;
// Now you can use pPartDocument...
12.85 HRESULT codes
Return codes from Inventor COM function calls are the normal COMcodes.
· Codes greater than or equal to 0 indicate success. · Codes less than 0 indicate failure.· You can use S_OK (defined as 0) to return you own HRESULT
success code.· S_FALSE is also a success return code (S_ = success). It could be
a simple question you asked COM, and does not fail.· You can use E_FAIL to return failure from your functions (E_=error)· You can also use E_INVALIDARG to return failure from your
function (again E_=error)
These four macros are defined for you in WinError.h:
#define SUCCEEDED(hr) (((HRESULT)(hr)) >= 0)#define FAILED(hr) (((HRESULT)(hr)) < 0)
#define S_OK ((HRESULT)0L)#define S_FALSE ((HRESULT)1L)
You can sometimes get the text interpretation of the error by using _com_error in something like this:
HRESULT hRes = pInvApp->get_ActiveDocument(&pDoc); if (FAILED(hRes)) { TRACE("Get Active Document Failed"); TRACE(_com_error(hRes).ErrorMessage(),MB_ICONSTOP);
159Programming Inventor in C++
(C) 2021 Owen F Ransen
return ; }
You can also use ShowCOMError
Or you can use:
TRACE("SetupDiGetDeviceInstanceId(): %s), _com_error(GetLastError()).ErrorMessage());
Some example codes (from one of the many Windows headers):
// Catastrophic failure//#define E_UNEXPECTED _HRESULT_TYPEDEF_(0x8000FFFFL)#if defined(_WIN32) && !defined(_MAC)
// Not implemented#define E_NOTIMPL _HRESULT_TYPEDEF_(0x80004001L)
// Ran out of memory#define E_OUTOFMEMORY _HRESULT_TYPEDEF_(0x8007000EL)
// One or more arguments are invalid#define E_INVALIDARG _HRESULT_TYPEDEF_(0x80070057L)
// No such interface supported#define E_NOINTERFACE _HRESULT_TYPEDEF_(0x80004002L)
// Invalid pointer#define E_POINTER _HRESULT_TYPEDEF_(0x80004003L)
// Invalid handle#define E_HANDLE _HRESULT_TYPEDEF_(0x80070006L)
// Operation aborted#define E_ABORT _HRESULT_TYPEDEF_(0x80004004L)
160 Autodesk Inventor Programming in C++ by Owen Ransen
(C) 2021 Owen F Ransen
// Unspecified error#define E_FAIL _HRESULT_TYPEDEF_(0x80004005L)
// General access denied error#define E_ACCESSDENIED _HRESULT_TYPEDEF_(0x80070005L)
See also this page for the error manager.
12.86 Add a mate constraint with two planes programatically
Here is a function which constrains two occurrences by mating twoWorkPlanes in the occurrences. It maybe has more error checkingthan normal, but it helps debug stuff sometimes. Note also that ithandles the proxies, so the caller of the function does not need toworry about those:
// Given two occurrences which contain workplanes to be mated together// this function creates a Mate constraint between thembool AddMateConstraintOfTwoPlanes (CComPtr<AssemblyComponentDefinition>&pAsmCompDef, CComPtr<ComponentOccurrence>& pOccA, CComPtr<WorkPlane>& pWorkPlaneA, CComPtr<ComponentOccurrence>& pOccB, CComPtr<WorkPlane>& pWorkPlaneB, const double kOffsetMm/*=0.0*/){ if ((pWorkPlaneA == nullptr) || (pWorkPlaneB == nullptr)) { gLogger.Printf(ekErrMsg, L"Errore: (pWorkPlaneA == nullptr) ||(pWorkPlaneB == nullptr)"); return false;
} else if ((pOccA == nullptr) || (pOccB == nullptr)) { gLogger.Printf(ekErrMsg, L"Errore: (pOccA == nullptr) || (pOccB ==nullptr)"); return false; }
CComPtr<WorkPlaneProxy> pWPProxyA ; HRESULT hRes = pOccA->CreateGeometryProxy (pWorkPlaneA,(IDispatch**)&pWPProxyA) ; if (FAILED(hRes)) { const CString kcsWorkPlaneName = GetWorkPlaneName(pWorkPlaneA); const CString kcsOccName = GetOccurrenceName(pOccA);
161Programming Inventor in C++
(C) 2021 Owen F Ransen
ShowCOMError (hRes,L"AMCOTP could not get pWPProxyA, plane=<%s>occurrence=<%s>.",kcsWorkPlaneName,kcsOccName) ; return false ; }
CComPtr<WorkPlaneProxy> pWPProxyB ; pOccB->CreateGeometryProxy (pWorkPlaneB,(IDispatch**)&pWPProxyB) ; if (FAILED(hRes)) { ShowCOMError (hRes,L"AMCOTP could not get pWPProxyB.") ; return false ; }
// Get the list of constraints of the assembly so you can add a new one CComPtr<AssemblyConstraints> pConstraintList ; hRes = pAsmCompDef->get_Constraints(&pConstraintList) ; if (FAILED(hRes)) { ShowCOMError (hRes,L"AMCOTP could not get constraints.") ; return false ; }
CComVariant varOffset(kOffsetMm/10.0); // Inventor wants cm CComPtr<MateConstraint> pMateConstraint = nullptr ; hRes = pConstraintList->AddMateConstraint(pWPProxyA, pWPProxyB, varOffset, kNoInference, kNoInference, gkvarEmpty, gkvarEmpty, &pMateConstraint); if (FAILED(hRes)) { ShowCOMError (hRes,L"AddMateConstraint failed") ; return false ; }
return true ;}
Note that we use proxies, which give the position of the planes in thecoordinate system of the assembly. I assume here that the twooccurrences have been taken from theAssemblyComponentDefinition.
Another thing to note (and maybe change with FlipNormal) whenmating WorkPlanes is the normal. Depending on the part this couldflip or rotate your part by 180 degrees.
162 Autodesk Inventor Programming in C++ by Owen Ransen
(C) 2021 Owen F Ransen
12.87 GetGeometryProxy
Here you go:
CComPtr<WorkPoint> pTuboOrig ; GetPartWorkPointByIndex(pTuboOrig,1,pTubeCompDef) ;
gLogger.Printf (ekLogMsg,L"TuboOrig è a %6.3f %6.3f %6.3f",pTuboOrig->Point->X,pTuboOrig->Point->Y,pTuboOrig->Point->Z) ;
CComPtr<WorkPointProxy> pTuboOrigInIam ; hRes = pTuboOcc->CreateGeometryProxy(pTuboOrig, (IDispatch**)&pTuboOrigInIam) ; if (FAILED(hRes)) { gLogger.Printf (ekErrMsg,L"CCollettore::AIT origine tubo") ; return false ; }
gLogger.Printf (ekLogMsg,L"Tubo è a %6.3f %6.3f %6.3f",pTuboOrigInIam->Point->X,pTuboOrigInIam->Point->Y,pTuboOrigInIam->Point->Z) ;
You get the first workpoint in the part, which is always 0,0,0 in thepart, and convert it to a proxy in the assembly workspace.
You will crash your program if you invert the order of the parameters,
163Programming Inventor in C++
(C) 2021 Owen F Ransen
idiot.
Here is a function do do that:
// Returns the position (in cm) of a part occurence within an assemblyCVec GetPartPositionInIamCm(CComPtr<ComponentOccurrence>& pOcc, CComQIPtr<PartComponentDefinition>& pCompDef){ CComPtr<WorkPoint> pOrigin ; GetPartWorkPointByIndex (pOrigin,1,pCompDef) ; CComPtr<WorkPointProxy> pOriginInAsm ; HRESULT hRes = pOcc->CreateGeometryProxy(pOrigin, (IDispatch**)&pOriginInAsm ) ; if (FAILED(hRes)) { gLogger.Printf (ekErrMsg,L"GPPIICproxy creation failed") ; return gkZeroVec ; }
CVec kvecOrigin (pOriginInAsm->Point->X,pOriginInAsm->Point->Y,pOriginInAsm->Point->Z) ;
return kvecOrigin ;}
CreateGeometryProxy may fail if the two inputs are not sensible. Forexample...
CComPtr<WorkPlaneProxy> pWPProxyA ; HRESULT hRes = pOccB->CreateGeometryProxy (pWorkPlaneA,(IDispatch**)&pWPProxyA) ;
...if pWorkPlaneA is in one part and pOccB references a different partyou'll get a 80004005 error in hRes.
See also this page.
12.88 Proxies, why and what?
When you have an part or workplane, for example, you can get thecoordinates of its points in the coordinate system of that part orworkplane. But what about when the part is an occurrence in anassembly. How can you get the coordinates of that part in theassembly? You use proxies. The same goes for other objects, here isan example with workplanes.
In a constraint for example there are two proxies called EntityOne and
164 Autodesk Inventor Programming in C++ by Owen Ransen
(C) 2021 Owen F Ransen
EntityTwo, which allow you to get to their respective occurrences:
Getting the proxy to the face (or workplane or point...) will allow you toget the occurrence from where the proxy was made (using).
Here is an example where (for example) 4 tubes have beenconstrained on another tube. When you get the proxies from theconstraint (for example the constraint between the third small tubeand the large
165Programming Inventor in C++
(C) 2021 Owen F Ransen
Here is another example, with workplane proxies inside an assembly:
166 Autodesk Inventor Programming in C++ by Owen Ransen
(C) 2021 Owen F Ransen
12.89 ErrorManager, errors and warnings, ShowCOMError andReturnAndShowCOMError
In InvSuppLib the file InvErrorHandling.cpp contains the errorhandling functions I use.
An example of an error message would be if you tried to create acircle in a sketch with negative diameter. You'll not get a nice "badradius" message from COM, just an "invalid parameter" message.
Have a look at the code for ShowCOMError. Not only does it give youdialog with the the text of the error code, but sometimes it gives youan extra hint about what caused the error. I add those hints as, dayby day, I understand them. You can do the same.
167Programming Inventor in C++
(C) 2021 Owen F Ransen
void ShowCOMError (HRESULT hRes, const wchar_t* constpszExtraMsg, ...) ;HRESULT ReturnAndShowCOMError (HRESULT hRes, const wchar_t* constpszExtraMsg=nullptr) ;void ShowInventorErrors () ;
Note also that the first function has trailing parameters ("..."), whichmeans it can be used just like printf. Note the %d and %s in thefollowing call:
ShowComError (hRes, L"The doodah called %d with diameter %.1fmm failed", pszDooDahName,kDooDahDiameter) ;
Extra tip: When using a COM get_ function you often pass theaddress of a pointer, which becomes set by the get_ function, andthe get_ function also returns a result code (an HRESULT) rememberto check both of them. For example the HRESULT may be S_OK (thefunction went well) but the pointer comes back nullptr (the object youwere looking for does not exist).
CComPtr<FeaturePatternElements> pPatternElements ; HRESULT hRes = pRecPattern->get_PatternElements (&pPatternElements) ; if (FAILED(hRes) || (pPatternElements == nullptr)) { // TWO CHECKS ShowCOMError (hRes,L"get_PatternElements failed") ; return false ; }
With some get_ functions you don't need to check the returnedpointer, but because I have a bad memory I often simply alwayscheck the pointer as well as the hRes.
See also HRESULT codes.
168 Autodesk Inventor Programming in C++ by Owen Ransen
(C) 2021 Owen F Ransen
12.90 Looping over views in sheets
This function will find a named view in a sheet of an IDW:
bool FindDrawingViewInSheetByName (CComPtr<DrawingView>& pView, CComPtr<Sheet>& pSheet, const wchar_t* const pszName) { if ((pSheet == nullptr) || (pszName == nullptr) || (wcslen(pszName) == 0)) { TRACE (L"FindDrawingViewInSheetByName, Bad inputparameters") ; return false ; }
CComPtr<DrawingViews> pViews ; HRESULT hRes = pSheet->get_DrawingViews (&pViews) ; if (FAILED(hRes) || (pViews == nullptr)) { ShowCOMError (hRes,L"FindDrawingViewInSheetByName,get_DrawingViews failed."); return false ; } const long ikNumViews = pViews->GetCount() ; for (long iView = 1 ; iView <= ikNumViews ; iView++) { CComPtr<DrawingView> pThisView ; hRes = pViews->get_Item (iView,&pThisView) ; if (FAILED(hRes) || (pThisView == nullptr)) { ShowCOMError (hRes,L"FindDrawingViewInSheetByName,get_Item(%d) failed.",iView); return false ; }
CComBSTR bstrViewName ; pThisView->get_Name (&bstrViewName) ;
TRACE ("Found a view called %s\n",bstrViewName) ;
if (wcscmp(CString(bstrViewName),pszName) == 0) { pView = pThisView ; return true ; } }
return false ;}
So you can find a named view inside a sheet..
169Programming Inventor in C++
(C) 2021 Owen F Ransen
12.91 Listing and checking constraints
This function goes over the constraints in an assembly checking thata given named constraint does not already exist:
bool ConstraintNameAlreadyExists (const CString& csNameToCheck, CComPtr<AssemblyComponentDefinition>& pAsmCompDef){ // Get the list of constraints of the assembly CComPtr<AssemblyConstraints> pConstraintList = nullptr ; HRESULT hRes = pAsmCompDef->get_Constraints(&pConstraintList); if (FAILED(hRes) || (pConstraintList == nullptr)) { ShowCOMError (hRes,L"ConstraintNameAlreadyExists couldnot get constraints.") ; return true ; // pretend it exists hopefully to stopfurther processing }
const long ikNumConstraints = pConstraintList->GetCount() ; for (int iConstraint = 1 ; iConstraint <= ikNumConstraints ;iConstraint++) { CComPtr<AssemblyConstraint> pConstraint = nullptr ; hRes =pConstraintList->get_Item(CComVariant(iConstraint),&pConstraint); if (FAILED(hRes) || (pConstraint == nullptr)) { ShowCOMError (hRes,L"ConstraintNameAlreadyExistscould not get constraint %d.",iConstraint) ; return true ; // pretend it exists hopefully to stopfurther processing }
CComBSTR bstrConstraintName ; pConstraint->get_Name(&bstrConstraintName) ; TRACE (L"Checking constraint <%s>\n",bstrConstraintName); if(CString(bstrConstraintName).CompareNoCase(csNameToCheck) == 0) { // A constraint with the given name already exists return true ; } }
170 Autodesk Inventor Programming in C++ by Owen Ransen
(C) 2021 Owen F Ransen
// If we get here then there are no constraints with the samename as csNameToCheck return false ;}
By the way, when your assemblies get even a bit complex it willprobably help you to name the constraints you add, using put_Name.
12.92 Saving apparently disabled (SilentOperation)
If you ever enable SilentOperation in your program remember to re-enable it just before your program exits. i.e:
m_pInvApp->SilentOperation = VARIANT_FALSE ;
12.93 WorkAxes in Inventor programs
In a Part there are always three standard WorkAxes, the X Y and Zaxes. Here is the "Z Axis":
171Programming Inventor in C++
(C) 2021 Owen F Ransen
When you search for axes by name, use "X Axis", "Y Axis",and "ZAxis" to get the standard ones. However remember that your use maynot be in an English speaking country, and in that case you can usethis function:
HRESULT GetStdWorkAxisByIndex (CComPtr<WorkAxis>& pWorkAxis, const UINT ikIndex, // 1 2 3 = X YZ CComPtr<PartComponentDefinition>&pPartCompDef) { if ((ikIndex < gikXIndex) || (ikIndex > gikZIndex)) { TRACE (L"GetWorkAxisByIndex index out of range: %d\n",gikXIndex) ; return (E_FAIL) ; }
172 Autodesk Inventor Programming in C++ by Owen Ransen
(C) 2021 Owen F Ransen
// Get the axis in the part by name... HRESULT hRes =pPartCompDef->WorkAxes->get_Item(CComVariant(ikIndex),&pWorkAxis); if (FAILED(hRes) || (pWorkAxis == nullptr)) { ShowCOMError (hRes,L"GetWorkAxisByIndex but 'get'failed\n"); return (E_FAIL) ; }
return (S_OK) ;}
Like many things WorkAxes are inside PartComponentDefinition, andyou can get hold of them like this:
CComPtr<PartComponentDefinition>& pPartCompDef ; ... pPartCompDef->WorkAxes->get_Item(CComVariant(pszWorkAxisName), &pWorkAxis);
Note that the plural of Axis is Axes, not Axiss!
12.94 Wrapping COM and C++
If you write a console EXE in C++ you should follow this high levelstructure:
int _tmain(int argc, _TCHAR* argv[]){
HRESULT Result = CoInitialize (NULL); // Start COM...
if (SUCCEEDED(Result))Result = YourInventorProgram();
CoUninitialize(); // ...end COM
return 0;}
173Programming Inventor in C++
(C) 2021 Owen F Ransen
In this way the smart pointers and COM objects will be constructedand destroyed properly, as long as you keep them on the stack (i.e.local to some function).
If you had a global variable like the error manager outside ofYourInventorProgram you would need to be able to handle it explictly,and you'd probably get errors when you program closes down(because the global pointer will be handled after CoUnitialize hasbeen called, and COM is no longer active).
12.95 Units when programming Inventor
Whatever units the user chooses to use (Inches or mm or feet or cmetc) internally Inventor only uses one of each type.
For example, even if the user sets inches as the linear unit, intenallyInventor uses Centimeters anyway. And you, as a programmer shoulduse Centimeters too.
This has implications for parameters, for example.
If you change an angular parameter, for example, remember to use
174 Autodesk Inventor Programming in C++ by Owen Ransen
(C) 2021 Owen F Ransen
radians, even though the user will see degrees.
12.96 Exporting Paramenters
To make model and user parameters visibile at a higher level than thepart in which they are contained use the iPart author to place them inthe pane on the left:
.
12.97 Placing objects in space Vector and Matrix
When you add an occurrence of a part you can specify the placementusing Vector and Matrix. The example below places the part at20,2,2:
// Need some transient geometry to add in a part... CComPtr<TransientGeometry> pTransGeom;
175Programming Inventor in C++
(C) 2021 Owen F Ransen
hr = pInvApp->get_TransientGeometry(&pTransGeom);
CComPtr<Matrix> pMatrix; // Defaults to 0,0,0 position hr = pTransGeom->CreateMatrix(&pMatrix);
CComPtr<Vector> pVector; // Create a Vector to modify the Matrix hr = pTransGeom->CreateVector(20,2,2,&pVector); pMatrix->SetTranslation (pVector,VARIANT_TRUE) ; CComPtr<ComponentOccurrence> pOcc2; hr = pOccs->Add(csFileName,pMatrix,&pOcc2) ;
The TransientGeometry pTransGeom object is an object whichcreates Vector and Matrix etc. It is a machine for making theseabstract objects.
Also note that the second parameter of SetTranslation is set toVARIANT_TRUE. That means "Yes, reset any rotation components inthe matrix". If you've only just created the matrix as in the aboveexample, there will be no rotation components inside the matrix, but Igenerally do the call with VARIANT_TRUE.
You can rotate and move an occurrence of a part like this:
CComPtr<TransientGeometry> pGeom = GetTransGeomPtr () ; pGeom->CreateMatrix(&pFinalMatrix); // First rotate ... CComPtr<Vector> pZAxis = nullptr; pGeom->CreateVector(0, 0, 1, &pZAxis);
CComPtr<Point> pOrigin = nullptr; pGeom->CreatePoint(0, 0, 0, &pOrigin); pFinalMatrix->SetToRotation(kRadians, pZAxis, pOrigin);
// Then shift .... CComPtr<Matrix> pTransMatrix; pGeom->CreateMatrix(&pTransMatrix); CComPtr<Vector> pTransVector; // Create a Vector to modify the Matrix pGeom->CreateVector(50.0,0.0,0.0,&pTransVector); pTransMatrix->SetTranslation (pTransVector,VARIANT_TRUE) ;
pFinalMatrix->PostMultiplyBy(pTransMatrix);
176 Autodesk Inventor Programming in C++ by Owen Ransen
(C) 2021 Owen F Ransen
12.98 ObjectCollections in the Inventor API (transient objectcollections)
Object collections can be used to make a list of already existingobjects. This list can then be used by your program to do repeatedoperations on those objects. Although the objects already exist theymay be in hard to get places, or in the wrong order to what you want.Or maybe the objects you want are a sub set of the all the objects inyour part or assembly.
Anyway, you need to get hold of the transient objects pointer from theInventor application:
CComPtr<Application> pInvApp ... ; CComPtr<TransientObjects> pTransientObjects ; pInvApp->get_TransientObjects (&pTransientObjects) ;
Or, if basing your programs on the book sources, you can use GetTransGeomPtr().
The TransientObjects pointor is the thing which allows you to createobject collections. Here is how to create an initially empty one:
CComPtr<ObjectCollection> pObjCollection = nullptr ; pTransientObjects->CreateObjectCollection(varEmpty,&pObjCollection) ;
Simply use the Add function to add objects to the collection. Here isan example of adding a WorkPlaneProxy to an object collection:
CComPtr<WorkPlaneProxy> pWPProxy = nullptr ; pTuboOcc->CreateGeometryProxy (pWP,(IDispatch**)&pWPProxy) ; pObjCollection->Add (pWPProxy) ;
Once you have created the list of objects you can get hold of them bypassing the index to the get_Item function:
177Programming Inventor in C++
(C) 2021 Owen F Ransen
CComPtr<WorkPlaneProxy> pHoleWPProxy = nullptr ; int iTroncNum = ..something starting a 1, 1 is the firstobject.... pObjCollection->get_Item(iTroncNum,(IDispatch**)&pHoleWPProxy) ;
I've removed all error checking from the fragments above.
12.99 Creating a new Part Document
Here's a function for doing it:
HRESULT CreateNewPartDoc(CComPtr<PartDocument>& pPartDoc, const wchar_t* const pszPartName)/*Given a name a new part document is created in Inventor with thatname.*/{ CComPtr<Application> pInventorApp = theApp.GetInvAppPtr() ;
CComVariant pSubDocType;CComBSTR sTemplate;HRESULT hr = pInventorApp->GetTemplateFile
(kPartDocumentObject, // We are creating a PartDocument kMetricSystemOfMeasure, // mm kDefault_DraftingStandard, pSubDocType, &sTemplate);
if (hr != S_OK) {return hr;
}
CComPtr<Document> pDoc; hr = pInventorApp->Documents->Add (kPartDocumentObject, sTemplate, VARIANT_TRUE, &pDoc); if (hr != S_OK) { return hr; }
178 Autodesk Inventor Programming in C++ by Owen Ransen
(C) 2021 Owen F Ransen
pPartDoc = CComQIPtr<PartDocument>(pDoc);
if ((pszPartName != nullptr) && (wcslen (pszPartName) > 0)) { BSTR bstrName ; pDoc->get_DisplayName (&bstrName) ; TRACE (L"\nFull document name was %s\n",bstrName) ;
pPartDoc->DisplayName = pszPartName ;
pDoc->get_DisplayName (&bstrName) ; TRACE (L"\nFull document name now is %s\n",bstrName) ;
::SysFreeString (bstrName) ; }
return hr;}
Which can be called like this:
CComPtr<PartDocument> pPartDocument ; HRESULT hRes = CreateNewPartDoc (pPartDocument,L"MAIN_TUBE"); if (FAILED(hRes)) { return ReturnAndShowCOMError (hRes,L"CreateMainTube,CreateNewPart failed") ; }
12.100How to extrude a sketch programatically
Here is a function which takes five parameters and creates a 3Dextruded feature in the part. The feature could be a hole, as well asnormal solid objects....
179Programming Inventor in C++
(C) 2021 Owen F Ransen
HRESULT ExtrudeSketch (const wchar_t* const pszExtrusionName, // name of created feature const double kHeightMm, const wchar_t* const pszSketchName, // which sketch to extrude const PartFeatureOperationEnumeOperation, // how to extrude const PartFeatureExtentDirectionEnumeDirection, CComPtr<PartComponentDefinition>&pPartCompDef)/*Given a height and a sketch name the sketch is extruded to thegiven height.
180 Autodesk Inventor Programming in C++ by Owen Ransen
(C) 2021 Owen F Ransen
The resultant feaure is placed inside pPartCompDef, and is calledpszExtrusionNameeOperation tells us whether to cut a hole or create a solidobject etc.eDirection tells us which direction to make the extrusion.*/{ // Get the sketch in the part by name... CComPtr<PlanarSketch> pSketch; HRESULT hRes =pPartCompDef->Sketches->get_Item(CComVariant(pszSketchName),&pSketch); if (FAILED(hRes) || (pSketch == nullptr)) { return ReturnAndShowCOMError (hRes,L"ExtrudeSketch butcould not get sketch by name\n"); } CComPtr<Profile> pProfile ; // This is the return value ofthe call to AddForSolid // and will be used when weextrude. CComVariant pSegs; // not used CComVariant pReserve; // not used hRes =pSketch->Profiles->AddForSolid(VARIANT_TRUE,pSegs,pReserve,&pProfile); if (FAILED(hRes) || (pProfile == nullptr)) { return ReturnAndShowCOMError (hRes,L"ExtrudeSketch butcould not AddForSolid for pProfile\n"); }
// Features are 3D objects. Get the list of them so we canadd to that list... CComPtr<PartFeatures> pListOfFeatures; hRes = pPartCompDef->get_Features(&pListOfFeatures); if (FAILED(hRes) || (pListOfFeatures == nullptr)) { return ReturnAndShowCOMError (hRes,L"ExtrudeSketch butcould not get_Features\n"); }
// Get the list of *extruded* features... CComPtr<ExtrudeFeatures> pListOfExtrusions; hRes =pListOfFeatures->get_ExtrudeFeatures(&pListOfExtrusions); if (FAILED(hRes) || (pListOfExtrusions == nullptr)) {
181Programming Inventor in C++
(C) 2021 Owen F Ransen
return ReturnAndShowCOMError (hRes,L"ExtrudeSketch butcould not get_ExtrudeFeatures\n"); }
// Now at last we can use the pProfile to create a newextrusion, adding it to the list // of extruded features. This is where we use the eOperationparameter CComPtr<ExtrudeDefinition> pExtrudeDef; hRes =pListOfExtrusions->CreateExtrudeDefinition(pProfile,eOperation,&pExtrudeDef); if (FAILED(hRes) || (pExtrudeDef == nullptr)) { return ReturnAndShowCOMError (hRes,L"ExtrudeSketch butcould not CreateExtrudeDefinition\n"); }
// Specify the distance and direction of the extrustion... // This function needs it in cm, so convert from mm to cm pExtrudeDef->SetDistanceExtent(_variant_t(kHeightMm/10.0),eDirection);
// Add the extrusion. CComPtr<ExtrudeFeature> pExtrude; hRes = pListOfExtrusions->Add (pExtrudeDef,&pExtrude); if (FAILED(hRes) || (pExtrude == nullptr)) { return ReturnAndShowCOMError (hRes,L"ExtrudeSketch butcould Add ExtrudeDefinition\n"); }
pExtrude->put_Name (CComBSTR (pszExtrusionName)) ;
return (hRes) ;}
Here are the possible values for the two enumerators used above:
182 Autodesk Inventor Programming in C++ by Owen Ransen
(C) 2021 Owen F Ransen
PartFeatureExtentDirectionEnumEnumerator ValueDescriptionkNegativeExtentDirection
20994
Extension in the negativedirection.
kPositiveExtentDirection
20993
Extension in the positivedirection
kSymmetricExtentDirection
20995
Extension in positive ANDnegative direction.
PartFeatureOperationEnumEnumerator Value DescriptionkCutOperation 2048
2Cut operation. (i.e. make ahole)
kIntersectOperation 20483
Intersect operation.
kJoinOperation 20481
Join operation.
kNewBodyOperation
20485
New Body operation.
kSurfaceOperation20484
Surface operation.
This image has used kCutOperation and kSymmetricExtentDirectionaround a center plane of a cylinder, the sketch contained a singlecircle:
183Programming Inventor in C++
(C) 2021 Owen F Ransen
12.101Transient Geometry
The transient geometry object is a "motor" which lets you create COMpoints, matrices, vectors, and so on. Think of it like this:
184 Autodesk Inventor Programming in C++ by Owen Ransen
(C) 2021 Owen F Ransen
// Set a reference to the transient geometry object. CComPtr<TransientGeometry> pTrGeom = GetTransGeomPtr();
// Draw a 4cm x 3cm rectangle with the corner at (0,0) CComPtr<Point2d> pPt1; // Create a 2d point hr = pTrGeom->CreatePoint2d(0.0,0.0,&pPt1); if (FAILED(hr)) return ReturnAndShowCOMError (hr,L" create 2d point failed") ;
CComPtr<Point> pPt; // Create a 3d point hr = pTrGeom->CreatePoint(0.5,0.5,0.0,&pPt); if (FAILED(hr)) return ReturnAndShowCOMError (hr,L" CreatePoint failed") ;
Note that above you've created a 2D point (CComPtr<Point2d>) and a3D point (CComPtr<Point>) using the TransientGeometry object. Here'show to create a matrix:
CComPtr<Matrix> pMatrix; hr = pTransGeom->CreateMatrix(&pMatrix);
And to create a Vector:
185Programming Inventor in C++
(C) 2021 Owen F Ransen
CComPtr<Vector> pVector; hr = pTransGeom->CreateVector(20,2,2,&pVector);
Note that these are "abstract geometrical" objects, not "concrete"CAD objects.
Note also that CComPtr will be initialised to nullptr automatically.
12.102Changing the application visibility
To set and get the visibility of Inventor:
// Obtain the 'Visible' property of the active application VARIANT_BOOL bVisible; Result = pInvApp->get_Visible(&bVisible); if (FAILED(Result)) return Result;
if (bVisible != VARIANT_TRUE){
pInvApp->Visible = VARIANT_TRUE ; }
...though you may well still see a tiny icon of Inventor at the top left ofyour screen.
12.103A matrix to rotate an object
When you insert a part in an assembly you can specify the initialposition and rotation. You do this by providing a matrix to the AddiPartMember call. Here is an example of how to create a matrixwhich will rotate the part around the Z axis by 180 degrees:
CComPtr<TransientGeometry> pTransGeom = GetTransGeomPtr () ; CComPtr<Matrix> pPosMatrix; pTransGeom->CreateMatrix(&pPosMatrix); // Defaults to origin
CComPtr<Vector> pZAxis = nullptr ; pTransGeom->CreateVector (0,0,1,&pZAxis);
186 Autodesk Inventor Programming in C++ by Owen Ransen
(C) 2021 Owen F Ransen
CComPtr<Point> pOrigin = nullptr ; pTransGeom->CreatePoint (0,0,0,&pOrigin);
pPosMatrix->SetToRotation (TwoPi,pZAxis,pOrigin) ;
...and when you call AddiPartMember you use the matrix like this:
pOccurrencesList->AddiPartMember (bstrFileName,pPosMatrix,_variant_t(bstrMemberName),&pOccurrence) ;
Note that SetToRotation requires radians, not degrees.
These two diagrams show the result of using a X-Axis rotation matrixwhen calling AddiPartMember:
187Programming Inventor in C++
(C) 2021 Owen F Ransen
Here is a code fragment which creates the matrix which does that:
CComPtr<Matrix> pRotXMatrix; pTransGeom->CreateMatrix(&pRotXMatrix); CComPtr<Vector> pXAxis = nullptr ; pTransGeom->CreateVector (0,1,0,&pXAxis); pRotXMatrix->SetToRotation (gkPi,pXAxis,pOrigin) ;
If you are using two planes in a constraint you can also sometimesuse FlipNormal to rotate the inserted object 180°
12.104Proxies, WorkAxes, Vectors and Points
Here is an example of getting the data about a work axis in part whichhas been inserted into an assembly:
CComPtr<Line> pAxisLine = nullptr ; p1stHoleWorkAxisProxy->get_Line (&pAxisLine) ;
188 Autodesk Inventor Programming in C++ by Owen Ransen
(C) 2021 Owen F Ransen
CComPtr<Point> pRootPoint ; pAxisLine->get_RootPoint (&pRootPoint) ; CComPtr<UnitVector> pAxisDir ; pAxisLine->get_Direction (&pAxisDir) ;
Now you can use that axis to form a rotation matrix:
CComPtr<Vector> pAxisVector = nullptr ; pTransGeom->CreateVector(pAxisDir->X,pAxisDir->Y,pAxisDir->Y,&pAxisVector) ;
pRotMatrix->SetToRotation (gkPi,pAxisVector,pRootPoint) ;
12.105WorkFeatures and iParts
If you have a workplane in a table based iPart (or even custom iPart)for that workplane to be visible in when inserted in an assembly (i.e.when it is an occurrence in an assembly) then you need to include itusing the iPart author.
If you don't do that you'll get a com error 80070057.
Here is the sequence:
189Programming Inventor in C++
(C) 2021 Owen F Ransen
In this way "TopWP" will be accessable with your program from theassembly.
Here's another graphical explanation:
190 Autodesk Inventor Programming in C++ by Owen Ransen
(C) 2021 Owen F Ransen
12.106What are PatternElements?
The FeaturePatternElements are the actual "copies" within a pattern,apart from the first one which is considered special.
Here's how you can list them
for (int i = 1; i <= pPatternElements->Count; i++) { CComPtr <FeaturePatternElement> pEle = nullptr ; hRes = pPatternElements->get_Item (i,&pEle) ; if (FAILED(hRes)) { ShowCOMError (hRes,L"EWTPFP, get_Item (%d) failed",ikNumber) ; return false ; }
gLogger.Printf(ekLogMsg,L"Element %d is a <%s>",i,GetObjTypeDesc(pEle->GetType())); }
191Programming Inventor in C++
(C) 2021 Owen F Ransen
12.107Listing the contents of Patterns
The parent objects of a Pattern are the objects selected to berepeated in the pattern. They could also be called source objects...
Here are a couple of functions illustrating how to get details frompatterns:
// Write out details of any rectangular patterns in this assemblyvoid ListRectPatterns(CComPtr<AssemblyComponentDefinition>& pAsmCompDef){ gLogger.Printf(ekLogMsg, L"LRP starting..."); CComPtr<OccurrencePatterns> pOccPatterns; pOccPatterns = pAsmCompDef->GetOccurrencePatterns(); if (pOccPatterns == nullptr) { gLogger.Printf(ekLogMsg, L"LRP no patterns..."); return ; }
for (int p = 1; p <= pOccPatterns->Count; p++) { gLogger.Printf(ekLogMsg, L"LRP pattern %d...",p); CComPtr<OccurrencePattern> pPattern; CComVariant varp(p); HRESULT hRes = pOccPatterns->get_Item(varp, &pPattern); if (FAILED(hRes) || (pPattern == nullptr)) { gLogger.Printf(ekLogMsg, L"LRP could not get %d...",p);
192 Autodesk Inventor Programming in C++ by Owen Ransen
(C) 2021 Owen F Ransen
continue; }
CComQIPtr<RectangularOccurrencePattern> pRectPattern; pRectPattern = pPattern; if (pRectPattern == nullptr) { continue; }
// Getting hold of the row and column counts is a bit tricky... CComVariant varRowCount (pRectPattern->RowCount->GetValue()); CComVariant varColCount (pRectPattern->ColumnCount->GetValue());
// Name of the pattern const CString kcsPatternName (pRectPattern->Name.GetBSTR()); const UINT ikNumSubItems = int(varRowCount.dblVal *varColCount.dblVal);
gLogger.Printf (ekLogMsg,L"Rect Pattern <%s> has %.1f rows and %.1fcolumns, numsub items=%d", kcsPatternName,varRowCount.dblVal,varColCount.dblVal,ikNumSubItems);
// Parent components are the objects which are the source objects ofthe array. CComPtr<ObjectCollection> pParentComponents; hRes = pRectPattern->get_ParentComponents(&pParentComponents); if (FAILED(hRes) || (pParentComponents == nullptr)) { gLogger.Printf(ekLogMsg, L"Could not get parent objects"); continue; }
// Now list the parent objects gLogger.Printf(ekLogMsg, L"LRP pattern %d has %d parent objects...",p,pParentComponents->Count);
for (int o = 1; o <= pParentComponents->Count ; o++) { CComQIPtr <ComponentOccurrence> pOcc; hRes = pParentComponents->get_Item (o,(IDispatch**)&pOcc); if (FAILED(hRes) || (pOcc == nullptr)) { gLogger.Printf(ekLogMsg, L"Skipping sources object %d %d", p,o); continue; }
_bstr_t DisplayName = pOcc->Get_DisplayName(); CString kcsDisplayName = CString (DisplayName.GetBSTR());
gLogger.Printf(ekLogMsg, L"Pattern %03d parent occurrence %03d is<%s>", p, o, kcsDisplayName); } }}
193Programming Inventor in C++
(C) 2021 Owen F Ransen
/*****************************************************************************************/
// List the features of any rectangular patterns in this partvoid ListRectPatternFeatures (CComPtr<PartComponentDefinition>& pPartCompDef){ HRESULT hRes ;
// Get the list of features... CComPtr<PartFeatures> pFeaturesList ; pPartCompDef->get_Features(&pFeaturesList) ;
// Get the list of rectangular features, we will add to this list.... CComPtr<RectangularPatternFeatures> pRectPatList ; pFeaturesList->get_RectangularPatternFeatures (&pRectPatList) ;
const long ikNumRecFeats = pRectPatList->GetCount() ;
for (int iRect = 1 ; iRect <= ikNumRecFeats ; iRect++) {
CComPtr <RectangularPatternFeature> pRectPatFeat ; hRes = pRectPatList->get_Item (CComVariant(iRect),&pRectPatFeat) ;
if (FAILED(hRes)) { ShowCOMError (hRes,L"ListRectangularPatternComponents, could notget rectangular pattern") ; return ; }
BSTR bstrName = pRectPatFeat->GetName () ;
CComPtr<Parameter> XCountParam ; pRectPatFeat->get_XCount (&XCountParam) ; /*const int ikXCount = XCountParam->GetValue () ;
TRACE (L"Component %d is called %s, and the x count is %d",iRect,bstrName,ikXCount) ;*/
CComPtr<FeaturePatternElements> pFeaturePatternElements ; pRectPatFeat->get_PatternElements (&pFeaturePatternElements) ;
const int ikNumElements = pFeaturePatternElements->GetCount() ; TRACE (L", this has %d FeaturePatternElements\n",ikNumElements) ;
for (int iElem = 1 ; iElem < ikNumElements ; iElem++) { CComPtr<FeaturePatternElement> pFeaturePatternElement ; pFeaturePatternElements->get_Item (iElem,&pFeaturePatternElement); }
::SysFreeString(bstrName); }}
194 Autodesk Inventor Programming in C++ by Owen Ransen
(C) 2021 Owen F Ransen
12.108Pattern counts
Once you get hold of a rectangular pattern you can count rows andcolumns as follows...
// Getting hold of the row and column counts is a bit tricky... CComVariant varRowCount (pRectPattern->RowCount->GetValue()); CComVariant varColCount (pRectPattern->ColumnCount->GetValue());
// Getting hold of the pattern name... const CString kcsPatternName (pRectPattern->Name.GetBSTR()); const UINT ikNumSubItems = int(varRowCount.dblVal *varColCount.dblVal);
gLogger.Printf (ekLogMsg,L"Rect Pattern <%s> has %.1f rows and %.1fcolumns, numsub items=%d", kcsPatternName,varRowCount.dblVal,varColCount.dblVal,ikNumSubItems);
Oddly enough the counts are double values, which is why we use .dblVal in the above code.
The code also illustrates getting hold of the pattern's name.
Patterns can have a count of 1.
12.109What sort of WorkFeature is this?
Unfortunately WorkPoint WorkAxis and WorkPlane objects do nothave a common parent. If you get a pointer to one of these thingsfrom an ObjectsCollection you have to work a bit harder than normalto get their type. Here is an example, assuming you already have anObjectsEnumerator and want to get hold of the iObj th item:
CComPtr<ObjectsEnumerator> pObjs = ... ; int iObj = ... ... CComPtr<WorkPlane> pWPlane = nullptr ; CComPtr<WorkPoint> pWPoint = nullptr ; CComPtr<WorkAxis> pWAxis = nullptr ; pObjs->get_Item (iObj,(IDispatch**)&pWPlane) ; pObjs->get_Item (iObj,(IDispatch**)&pWPoint) ;
195Programming Inventor in C++
(C) 2021 Owen F Ransen
pObjs->get_Item (iObj,(IDispatch**)&pWAxis) ; if ((pWPlane != nullptr) && (pWPlane->GetType() ==kWorkPlaneObject)) { // pWPlane is a valid workplane } else if ((pWPoint != nullptr) && (pWPoint->GetType() ==kWorkPointObject)) { // pWPoint is a valid workpoint
} else if ((pWAxis != nullptr) && (pWAxis->GetType() ==kWorkAxisObject)) { // pWAxis is a valid axis
} else { // This is probably an error }
.
12.110IDispatch
You often need to cast pointers to objects into IDispatch* orIDispatch** when calling functions in the Inventor C++ COM API.Here are some examples, showing how to cast from various Inventorpointers to an IDispatch* :
Add a sketch based on a workplane:
CComPtr<WorkPlane> pWorkPlane ; hRes = pSketches->Add (_variant_t((IDispatch*)pWorkPlane), VARIANT_FALSE, &pNewSketch);
Add a workplane based on an existing workplane:
CComPtr<WorkPlane> pWorkPlane... ; CComPtr<WorkPlane> pOffsetWorkPlane ; hRes = pWorkPlanesList->AddByPlaneAndOffset (_variant_t((IDispatch*)pWorkPlane),// "starting" plane CComVariant(kTubeDiam/2.0), // how much to offset VARIANT_FALSE, // Construction?
196 Autodesk Inventor Programming in C++ by Owen Ransen
(C) 2021 Owen F Ransen
&pOffsetWorkPlane) ; // Return value of this call
Add a workpoint based on a sketchpoint:
CComPtr<SketchPoint> pSketchPoint... ; CComPtr<WorkPoint> pWorkPoint ; hRes = pWorkPointsList->AddByPoint (_variant_t((IDispatch*)pSketchPoint),VARIANT_FALSE,&pWorkPoint) ; if (FAILED(hRes) || (pWorkPoint == nullptr)) { return ReturnAndShowCOMError (hRes,L"AddWorkPointAtSketchPoint, Add workpoint failed") ; }
Create a proxy geometry from an occurrence and a workplane:
CComPtr<WorkPlaneProxy> pWPProxyA ; pOccurrence->CreateGeometryProxy (pWorkPlaneA,(IDispatch**)&pWPProxyA) ;
12.111AddByPlaneAndOffset example
Here is an example of creating an offset workplane from a standardworkplane, then setting it's name and making it visible in theassembly in which it exists:
CComPtr<WorkPlanes> pWorkPlanesList; hRes = pPartCompDef->get_WorkPlanes(&pWorkPlanesList);
CComPtr<WorkPlane> pCorpoCollXYWorkPlane; GetStdWorkPlaneByIndex(pCorpoCollXYWorkPlane, gikXYPlaneIndex,pPartCompDef);
CComPtr<WorkPlane> pOffsetWorkPlane;
const double kcmOffsetIn = 5.50; // 55mm
hRes = pWorkPlanesList->AddByPlaneAndOffset(pCorpoCollXYWorkPlane, //"starting" plane CComVariant (55.0), //how much to offset VARIANT_FALSE, //
197Programming Inventor in C++
(C) 2021 Owen F Ransen
Construction? &pOffsetWorkPlane); //Return value of this call if (SUCCEEDED(hRes)) { // Set the name so it is easily found by other parts of theprogram... pOffsetWorkPlane->Name = L"TuboIntBase";
// Export the feature so it is accessible in assemblies... pOffsetWorkPlane->Exported = VARIANT_TRUE; }
12.112Interrogating rectangular patterns
Here is a rectangular pattern inside an assembly:
If you have a PartComponentDefinition which contains a
198 Autodesk Inventor Programming in C++ by Owen Ransen
(C) 2021 Owen F Ransen
RectangularPatternFeature use this fragment of code to find out basicdata:
CComPtr<PartFeatures> pFeatures ; hRes = pBlockCompDef->get_Features (&pFeatures) ;
CComPtr<RectangularPatternFeatures> pRectPatList ; hRes = pFeatures->get_RectangularPatternFeatures (&pRectPatList) ;
// Pretend we know that we want the first rectangular pattern... CComPtr <RectangularPatternFeature> pRectPatFeat ; hRes = pRectPatList->get_Item (CComVariant(1),&pRectPatFeat) ;
CComPtr<Parameter> pXCountParam ; pRectPatFeat->get_XCount (&pXCountParam) ; int iXCount = 1 ; // note this initialization! if (pXCountParam != nullptr) { iXCount = pXCountParam->GetValue () ; // only if not nullptr! }
CComPtr<Parameter> pYCountParam ; pRectPatFeat->get_YCount (&pYCountParam) ; int iYCount = 1 ; // note this initialization! if (pYCountParam !=nullptr) { iYCount = pYCountParam->GetValue () ; // only if not nullptr! }
TRACE (L"The rectangular feature has %d by %d items\n",iXCount,iYCount) ;
Note the strangeness of the fact that there is no Y count if the patternis a linear array with , for example, 5 X items. That is why I set iYCount to 1 and change it only if pYCountParam is not nullptr.
Note also that you should check hRes, I've not done it for clarity here.
12.113Name of part in a component occurrence
Here is a function which will return the component occurrence (withinan assembly) of a given name.
HRESULT GetComponentOccurrenceByName (CComPtr<ComponentOccurrence>& pCompOccRet,
199Programming Inventor in C++
(C) 2021 Owen F Ransen
const wchar_t* constpszOccName, CComQIPtr<AssemblyDocument>pAssemblyDoc){ // Init for safety pCompOccRet = nullptr ;
// Get assembly component definition CComPtr<AssemblyComponentDefinition> pAssemblyCompDef = nullptr; HRESULT hRes =pAssemblyDoc->get_ComponentDefinition(&pAssemblyCompDef); if (FAILED(hRes) || (pAssemblyCompDef == nullptr)){ return ReturnAndShowCOMError(hRes,L"GetComponentOccurrenceByName, get_ComponentDefinition failed "); }
// Get the ComponentOccurrences collection for the assemblydocument CComPtr<ComponentOccurrences> pOccs; hRes = pAssemblyCompDef->get_Occurrences(&pOccs); if (FAILED(hRes) || (pOccs == nullptr)){ return ReturnAndShowCOMError (hRes,L"GetComponentOccurrenceByName, get_Occurrences failed "); }
long lNoOccs; hRes = pOccs->get_Count(&lNoOccs); if (FAILED(hRes)) { ReturnAndShowCOMError (hRes,L"GetComponentOccurrenceByName, get_Count failed "); }
TRACE (L"GetComponentOccurrenceByName, there are %doccurrences\n",lNoOccs);
//iterate through the current level of occurrencesfor (long lOccCount=1; lOccCount <= lNoOccs; ++lOccCount) {
CComPtr<ComponentOccurrence> pThisCompOcc = nullptr ; hRes = pOccs->get_Item(lOccCount, &pThisCompOcc); if (FAILED(hRes) || (pThisCompOcc == nullptr)){ ShowCOMError(hRes,L"GetComponentOccurrenceByName,
200 Autodesk Inventor Programming in C++ by Owen Ransen
(C) 2021 Owen F Ransen
get_Item failed "); return hRes ; }
CComPtr<ReferencedFileDescriptor> pRefFileDesc = nullptr; pThisCompOcc->get_ReferencedFileDescriptor(&pRefFileDesc) ; if (FAILED(hRes) || (pThisCompOcc == nullptr)){ ShowCOMError(hRes,L"GetComponentOccurrenceByName,get_ReferencedFileDescriptor failed "); return hRes ; } CComBSTR bstrDisplayName; // ::SysFreeString not requiredbecause CComBSTR, not BSTR hRes = pRefFileDesc->get_DisplayName (&bstrDisplayName) ; if (FAILED(hRes) || (pThisCompOcc == nullptr)){ ShowCOMError(hRes,L"GetComponentOccurrenceByName,get_DisplayName failed "); return hRes ;
} else {TRACE (L"Component occurrence %02d <%s>\n"
,lOccCount,bstrDisplayName); if (_wcsicmp(bstrDisplayName,pszOccName)==0) { pCompOccRet = pThisCompOcc ; } }
if (pCompOccRet != nullptr) { // We can get out return (S_OK) ; } }
TRACE (L"Could not find an occurrence called <%s>\n",pszOccName) ;
return (E_FAIL) ;}
Basically you get the name of the occurrence's part using theoccurrences ReferencedFileDescriptor .
201Programming Inventor in C++
(C) 2021 Owen F Ransen
12.114Add an occurrence to an assembly does not work
When you add an .ipt part to an .iam assembly you need to pass thecorrect sort of parameter to the Add function. For example this will notwork:
CComPtr<ComponentOccurrence> pCyl2Occ = nullptr;hRes = pOccurrencesList->Add (L"C:\\TEST\\Cyl2.ipt",pPosMatrix,&pCyl2Occ) ;
...but this will...
CComPtr<ComponentOccurrence> pCyl2Occ = nullptr;hRes = pOccurrencesList->Add (CComBSTR(L"C:\\TEST\\Cyl2.ipt"),pPosMatrix,&pCyl2Occ) ;
The difference is that the first call does not cast to CComBSTR, thesecond, working version, does.
12.115Listing constraints in an assembly programatically
Here is a code fragment showing how to list constraints and castEntityOne and EntityTwo into appropriate proxies. Graphically theconstraint and two proxies look like this:
202 Autodesk Inventor Programming in C++ by Owen Ransen
(C) 2021 Owen F Ransen
// Get the list of constraints of the assembly so you can adda new one CComPtr<AssemblyConstraints> pConstraintList = nullptr ; hRes = pAssemblyCompDef->get_Constraints(&pConstraintList) ; if (FAILED(hRes) || (pConstraintList == nullptr)) { TRACE (L"Could not get constraints.") ; return ; }
// List the two entities of each MateConstraint... for (int i = 1 ; i <= pConstraintList->Count ; i++) { CComPtr<AssemblyConstraint> pConstraint = nullptr ; pConstraintList->get_Item (CComVariant(i),&pConstraint) ; CComQIPtr<MateConstraint> pMate (pConstraint) ; if (nullptr != pMate) { // This is a mate constraing, show more data aboutit... IDispatchPtr pEnt1 = pMate->EntityOne ; IDispatchPtr pEnt2 = pMate->EntityTwo ; TRACE (L" Two parts are %p %p\n",pEnt1,pEnt2) ; CComQIPtr<FaceProxy> pFace1 =
203Programming Inventor in C++
(C) 2021 Owen F Ransen
CComQIPtr<FaceProxy>(pEnt1); CComQIPtr<WorkPlaneProxy> pWP1 =CComQIPtr<WorkPlaneProxy>(pEnt1); if (pFace1 != nullptr) { TRACE (L" Ent1 is a face proxy...\n") ; } else if (pWP1 != nullptr) { TRACE (L" Ent1 is a workplane proxy...\n") ; CComPtr<ComponentOccurrence> pContOcc =pWP1->ContainingOccurrence ; if (pContOcc != nullptr) { CComPtr<ReferencedFileDescriptor> pFileDesc= nullptr ; pContOcc->get_ReferencedFileDescriptor(&pFileDesc) ; if (pFileDesc != nullptr) { CComBSTR bstrFullFileName ; pFileDesc->get_FullFileName(&bstrFullFileName) ; TRACE (L" Ent1 full file name is %s\n",bstrFullFileName) ; } }
} else { TRACE (L" Ent1 This is neither a face orworkplane proxy\n") ; } } }
12.116Listing members in an iPartFactory programatically
Here is how to list members of an iPartFactory, starting with thePartDocument:
// Open the standard part... CComPtr<PartComponentDefinition> pTroncPartCompDef = nullptr; CComPtr<PartDocument> pTroncPartDoc = nullptr ; HRESULT hRes = OpenPart(pTroncPartCompDef,pTroncPartDoc,gkcsTroncFactory,pInvApp) ;
// Check that it is an iPartFactory...
204 Autodesk Inventor Programming in C++ by Owen Ransen
(C) 2021 Owen F Ransen
if (pTroncPartCompDef->IsiPartFactory == VARIANT_FALSE) { gLogger.Printf (ekImmediateErrorMsg,L"%s non e' uniPartFactory",gkcsTroncFactory) ; // This is NOT an iPartFactory return ; }
/* * Get the iPartFactory from the component definition... */ CComPtr<iPartFactory> piPartFactory = nullptr ; hRes =pTroncPartCompDef->get_iPartFactory (&piPartFactory) ;
/* * Get the rows of the factory, each row corresponds to a"member"... */ CComPtr<iPartTableRows> piPartTableRows = nullptr ; piPartFactory->get_TableRows (&piPartTableRows) ;
/* * Loop over the members in the table, printing Member... */ for (int iRow = 1 ; iRow <= piPartTableRows->Count ; iRow++){ CComPtr<iPartTableRow> piPartRow ; piPartTableRows->get_Item (iRow,&piPartRow) ; const int ikNumColumns = piPartRow->GetCount() ; BSTR bstrMember = nullptr ; piPartRow->get_MemberName (&bstrMember) ; TRACE (L" Row %03d:%s has %d things\n",iRow,LPCSTR(bstrMember),ikNumColumns) ; for (int iCol = 1 ; iCol <= ikNumColumns ; iCol++) { CComPtr<iPartTableCell> piPartTableCell = nullptr ; piPartRow->get_Item(CComVariant(iCol),&piPartTableCell) ;
CComBSTR bstrCellString ; piPartTableCell->get_Value (&bstrCellString) ; TRACE (L" iRow %d iCol %d has value %s\n",iRow,iCol,LPWSTR(bstrCellString)) ; }
205Programming Inventor in C++
(C) 2021 Owen F Ransen
::SysFreeString (bstrMember) ; }
As usual there's not as much error checking in the source above asthere should be. That last inner loop could use a function like this:
wchar_t* GetStringFromiPartTableRowCell (wchar_t* const szCellContents, size_t ikBufferSize, const UINT ikCol, CComPtr<iPartTableRow> piPartRow) { if (int(ikCol) > piPartRow->GetCount()) { szCellContents[0] = char(0) ; return szCellContents ; }
CComPtr<iPartTableCell> piPartTableCell ; piPartRow->get_Item (CComVariant(ikCol),&piPartTableCell) ;
CComBSTR bstrCellString ; piPartTableCell->get_Value (&bstrCellString) ; wcscpy_s (szCellContents,ikBufferSize,LPWSTR(bstrCellString)) ; return szCellContents ;}
See also iPartMember. and
12.117PartComponentDefinition from an occurrence
If you have an occurrence of a part, you can get thePartComponentDefinition of that part by using the Definition memberand a cast as shown below:
CComQIPtr<PartComponentDefinition> pCompDef =CComQIPtr<PartComponentDefinition>(pTuboOcc->Definition);
You are casting from a ComponentDefinition to aPartComponentDefinition, note the use of CComQIPtr.
CComQIPtr<PartComponentDefinition> pCompDef =pTuboOcc->Definition;
206 Autodesk Inventor Programming in C++ by Owen Ransen
(C) 2021 Owen F Ransen
It may be that you do not need the cast. Check the result though
12.118AddiPartMember
You can add an iPart member (i.e. an instance of an iPart from theiPart's table) to an assembly by using the function AddiPartMember.The easiest type of call is when you know the index of the row of thetable, for example row 3 in the example below:
CComPtr<ComponentOccurrence> pPartOcc = nullptr;pOccurrencesList->AddiPartMember (CComBSTR("My_Factory.ipt"), //iPart factory file pPosMatrix, CComVariant(3), // Row of theiPart Factory Table, the "member" &pPartOcc) ;
You can also specify directly the member to insert using the Memberstring:
CComPtr<TransientGeometry> pTransGeom = ...CComPtr<Matrix> pPosMatrix;pTransGeom->CreateMatrix(&pPosMatrix); // Defaults to 0 0 0
CComPtr<ComponentOccurrence> pTroncOcc ;CComBSTR bstrTronchettiFile (L"C:\\TEST\\TEST_IPART.ipt") ;CComBSTR bstrMember (L"30086486") ; // the Member valuepOccurrencesList->AddiPartMember (bstrTronchettiFile,pPosMatrix,_variant_t(bstrMember),&pTroncOcc) ;
As a reminder, the Member column is the first in the iPart table:
207Programming Inventor in C++
(C) 2021 Owen F Ransen
See also iPartFactory, listing members, and rotating parts inassemblies.
12.119Getting the workplanes of a part occurrence in an assembly
What you need to do here is get the occurrence and then get the partcomponent definition of it. This requires a cast...
CComQIPtr<PartComponentDefinition> pPartCompDef =CComQIPtr<PartComponentDefinition>(pOcc->Definition);
208 Autodesk Inventor Programming in C++ by Owen Ransen
(C) 2021 Owen F Ransen
You need to be sure that the occurrence point to a part, get itsDefinition, then cast it from ComponentDefinition toPartComponentDefinition, as shown above. Now you can get theworkplanes from the pPartCompDef, for example:
CComPtr<WorkPlanes> pWorkPlaneList ; HRESULT hRes = pPartCompDef->get_WorkPlanes(&pWorkPlaneList);
12.120SubOccurrences
SubOccurrences of an assembly can be parts or assemblies. Givenan assembly this code fragment lists their names:
CComPtr<ComponentOccurrencesEnumerator> pCompOccsEnum = nullptr ; pAttOcc->get_SubOccurrences (&pCompOccsEnum) ; UINT iNumSubOccurrences = pCompOccsEnum->Count ; for (UINT i = 1 ; i <= iNumSubOccurrences ; i++) { TRACE (L"Occ%d = %s\n",pCompOccsEnum->Item [1]->Name ) ; }
12.121SaveAs function
Be careful with this function. It will accept a wchar_t but will not workunless the wchar_t is wrapped inside a CComBSTR type:
hRes = pPartDoc->SaveAs (CComBSTR(L"C:\\CHS_LHS_COLL\\This.ipt"),VARIANT_TRUE) ; if (FAILED(hRes)){ ShowCOMError(hRes,L"CCollettore::CreateCollectorMainTubePart, save failed."); return (false) ; }
That last parameter is:
209Programming Inventor in C++
(C) 2021 Owen F Ransen
· VARIANT_TRUE - any existing file will be overwritten· VARIANT_FALSE - an existing file will not be overwritten and the
function will fail.
Here is another example with an assembly document:
CComQIPtr<AssemblyDocument> pAssemblyDoc ; ...init pAssemblyDoc ... CString csFullAssemblyName (L"C:\\YOUR_TEST\\Test_Assembly.iam") ; pAssemblyDoc->SaveAs(CComBSTR(csFullAssemblyName),VARIANT_TRUE) ;
Gotcha: SaveAs will save to a copy and not change the name of thedocument. So inside your program you'll still have the original. If youwant operate on the copy you'll have to read it in again.
If you want to save the current in memory document with a differentname you can do something like this:
// In this case we just change the name and save it without closing... CComBSTR bstrFullFileName(m_csAssemblyFullFileName); // Convert fromCString to BSTR pAssemblyDoc->PutFullFileName(bstrFullFileName.m_str); // Set the name(full file name ofthe document) pAssemblyDoc->Save(); // Save it with the new name
See also Save. After the first save FullFileName is read only.
12.122Save programatically
The Save function can be used like this:
CComQIPtr<AssemblyDocument> pAssemblyDoc ; ...init pAssemblyDoc ... CString csFullAssemblyName(L"C:\\TEST_DIR\\Test_Assembly.iam") ;
210 Autodesk Inventor Programming in C++ by Owen Ransen
(C) 2021 Owen F Ransen
pAssemblyDoc->put_FullFileName (CComBSTR(csFullAssemblyName)); pAssemblyDoc->Save () ;
Note that in this example I've changed the full filename of theassembly, and then called Save.
If the file already exists then a Save dialog will pop up, otherwise thesave will run silently. Save will not silently overwrite an existing file,check the return value if you find your changes are not being saved.
Note also that if the doc is new, and so does not have a name, theSave will fail with error 80004005. This is because of the emptyfilename. Here is an example of avoiding that error:
/* * This is a new drawing and so had no name. Without a name * the Save function will not work. So set the name... */ CString csFullIDWName (kcsFullAssemblyName) ; ChangeExtension (csFullIDWName,L"IDW") ; pDrawingDoc->put_FullFileName (CComBSTR(csFullIDWName)) ;
/* * Now you can save, since the doc has a name */ hRes = pDrawingDoc->Save () ; if (FAILED(hRes)) { // Check anyway... CComBSTR bstrFullFileName ; pDrawingDoc->get_FullFileName (&bstrFullFileName) ; ShowCOMError (hRes,L"Saving drawing document<%s>",bstrFullFileName) ; }
See also SaveAs, which allows you to specify overwrite and saves acopy.
12.123FullDocumentName and GetLocationFoundIn
These two functions tell you about the "location" of the part.
{ // Show in what current project the part is... CComBSTR bstrLocationName; LocationTypeEnum eType; pPartDoc->GetLocationFoundIn(&bstrLocationName, &eType);
211Programming Inventor in C++
(C) 2021 Owen F Ransen
TRACE (L"GetLocationFoundIn Location = <%s>, enum = %d",bstrLocationName, eType); // For example: <WorkSpace>, enum = 45057, read from the project file,I think }
{ // Show the simple full file path of the part... _bstr_t fdn = pPartDoc->GetFullDocumentName (); TRACE (L"FullDocumentName = <%s>",LPCWSTR (fdn));"C:\\WillyWonker\\Chocolate.ipt" }
12.124Close function, Inventor API
Here's an example of using the Close function on a PartDocument.Imagine we have opened and modified and existing file. Next we SaveAs to create a copy of our original part, then we Close theoriginal without saving:
// VARIANT_TRUE = Overwrite hRes = pPartDoc->SaveAs (CComBSTR(csPartFullFileName),VARIANT_TRUE) ;
// VARIANT_TRUE means skip save and don't show any dialogs hRes = pPartDoc->Close(VARIANT_TRUE) ;
Notice the comment just before the call to Close. We've alreadysaved the part with SaveAs, and we just want to close the document,and we don't want any further saving (or dialogs) to come up. HenceVARIANT_TRUE (which means SkipSave) is used.
12.125Making workfeatures of a part invisible in the assembly
Work features which are exported are in a table based iPart are oftenvisible in the assembly into which the part is placed. It seems to bethe default action.
To make these work features invisible in the assembly you need touse a function like this:
// pOcc is the occurrence of a part in an assembly. This function which switchon or off// the visibility of a workplane of the part in the assembly. It does notaffect the// visibility in the part file.void SetWorkPlaneVisibility(CComPtr<ComponentOccurrence>& pOcc, const CString&
212 Autodesk Inventor Programming in C++ by Owen Ransen
(C) 2021 Owen F Ransen
kcsWorkPlaneName, const bool kbVisible){ CComPtr<ComponentDefinition> pDef = nullptr; HRESULT hRes = pOcc->get_Definition(&pDef); if (FAILED(hRes)) { ShowCOMError(hRes, L"SWPV could not get definition %s",kcsWorkPlaneName); return; }
CComQIPtr<PartComponentDefinition> pPartCompDef = pDef;
CComPtr<WorkPlane> pWorkPlane=nullptr ; hRes = pPartCompDef->WorkPlanes->get_Item(CComVariant (kcsWorkPlaneName),&pWorkPlane); if (FAILED(hRes)) { ShowCOMError(hRes, L"SWPV, could not get workplane called %s",kcsWorkPlaneName); return; }
// Get the proxy which is how the part is instantiated in the assembly CComPtr<WorkPlaneProxy> pWPProxy ; hRes = pOcc->CreateGeometryProxy (pWorkPlane,(IDispatch**)&pWPProxy) ; if (FAILED(hRes)) { ShowCOMError(hRes, L"Could not get proxy of %s",kcsWorkPlaneName); return; }
if (kbVisible) { hRes = pWPProxy->put_Visible(VARIANT_TRUE);
} else { hRes = pWPProxy->put_Visible(VARIANT_FALSE); }
if (FAILED(hRes)) { ShowCOMError(hRes, L"Could not get set proxy visibility of %s",kcsWorkPlaneName); }}
/********************************************************************************************************/
213Programming Inventor in C++
(C) 2021 Owen F Ransen
12.126Visibility programatically in Inventor
Here is an example of how to set the visibility of a workpoint
CComPtr<WorkPoint> pWorkPoint = nullptr ; GetWorkPointByName (pWorkPoint,csPointName,pPartCompDef); if (bMakeVisible)) { pWorkPoint->put_Visible (VARIANT_TRUE) ;
} else { pWorkPoint->put_Visible (VARIANT_FALSE) ; }
12.127AddCustomiPartMember details and tips
Look at this call:
pOccs->AddCustomiPartMember(strFactoryFile, // This is thesource file of the object to create pMatrix, // This is where toplace the created custom iPart strFullFileName, // This is theresulting file of the created object varEmpty, // Usually unusedwith custom iParts, hence varEmpty. oleSafeArray, // Parameters, incolumn order &pCyl1Occ) ;
varEmpty will be something like this:
CComVariant varEmpty ;
The creation of oleSafeArray is explained here. However rememberthat the values must be in column order, for example:
BSTR strParams[] =
214 Autodesk Inventor Programming in C++ by Owen Ransen
(C) 2021 Owen F Ransen
{ CString("35 mm").AllocSysString(), // Diameter CString("1.5 mm").AllocSysString(), // Thickness CString("350 mm").AllocSysString(), // Length CString("10").AllocSysString(), // R1Angle CString("20").AllocSysString(), // R2Angle }; const int ikNumParams = sizeof(strParams)/sizeof(strParams[0]) ;
COleSafeArray oleSafeArray; oleSafeArray.CreateOneDim(VT_BSTR, ikNumParams, strParams);
The call may fail for one of these reasons:1. The columns you have specified don't make solid sense, an outer
diameter smaller than an inner diameter for example.2. The factory file (first parameter) does not exist.
The two filenames can be created like this:
CComBSTR strFactoryFile(L"C:\\CHS_LHS_COLL\\Tube-Custom.ipt"); CComBSTR strFullFileName(L"C:\\CHS_LHS_COLL\\Tube_999.ipt") ;
12.128Add in the occurrence of a custom iPart into an assembly
The most difficult part of adding a custom iPart into an assembly isunderstanding how to specify the parameters.
The first step is to get hold of the list of occurrences so you can add anew occurrence to the list.
Then you create a matrix and a vector to specify the position (and anyrotations etc.) of the object.
Then you create a list of parameters in column order of the iPart.When you use the iPart Author you'll see the custom parameters inpurple. Use that order. These parameters have to be created in aCOleSafeArray.
215Programming Inventor in C++
(C) 2021 Owen F Ransen
Now you are ready to call AddCustomiPartMember with the objects youcreated in the previous steps.
Here is a fragment which assumes you already have anAssemblyComponentDefinition:
CComPtr<ComponentOccurrences> pOccs; hRes = pAssemblyCompDef->get_Occurrences(&pOccs);
// This is the name of the iPart factory, from which customiParts will be created... CComBSTR strFactoryFile(L"C:\\TEST\\CustomCylinder.ipt") ; // Get hold of the transient geometry pointer to create thematrix which says // where to place the custom iPart... CComPtr<TransientGeometry> pTransGeom = GetTransGeomPtr() ; CComPtr<Matrix> pMatrix; // Defaults to 0,0,0 position pTransGeom->CreateMatrix(&pMatrix); CComPtr<Vector> pVector; // Create a Vector to modify theMatrix pTransGeom->CreateVector(2,2,0,&pVector); hRes = pMatrix->SetTranslation (pVector,VARIANT_TRUE) ;
// This is the name of the output file, the iPart createdfrom the factory file... CComBSTR strFullFileName(L"C:\\CHS_LHS_COLL\\CUSTOMCYL2.ipt"); CComVariant varEmpty ; // Nothing because we are notselecting a row
// We are not selecting a row but we are changing parameters.Here is how // we specify those parameters...#define NUM_PARAMS 2 BSTR strBSTR[NUM_PARAMS] = { CString("20 cm").AllocSysString(), CString("10 cm").AllocSysString(), };
COleSafeArray oleSafeArray; oleSafeArray.CreateOneDim(VT_BSTR, NUM_PARAMS, strBSTR);
216 Autodesk Inventor Programming in C++ by Owen Ransen
(C) 2021 Owen F Ransen
CComPtr<ComponentOccurrence> pCyl1Occ; pOccs->AddCustomiPartMember(strFactoryFile,pMatrix,strFullFileName,varEmpty,oleSafeArray,&pCyl1Occ) ;
I've not yet found out how to create the parameter list when not usingMFC. COleSafeArray is an MFC object.
See also AddCustomiPartMember details and tips.
12.129Occurrences and component definitions
An occurrence is like an XREF insert in AutoCAD. Occurrences exist,for example, inside assemblies. It is an instance of a part. Thediagram below shows that an assembly has inside it anAssemblyComponentDefinition, and inside that is a list of occurrences(among ther things):
217Programming Inventor in C++
(C) 2021 Owen F Ransen
Here is some code to list the occurrences in an assembly:
// Get assembly component definitionCComPtr<AssemblyComponentDefinition> pAssemblyCompDef;HRESULT Result = pAssemblyDoc->get_ComponentDefinition(&pAssemblyCompDef);
// Get the ComponentOccurrences collection for the assembly documentCComPtr<ComponentOccurrences> pOccs;Result = pAssemblyCompDef->get_Occurrences(&pOccs);
long lNoOccs; Result = pOccs->get_Count(&lNoOccs);
TRACE("There are %d occurrences\n",lNoOccs);
//iterate through the current level of occurrenceslong lOccCount;
218 Autodesk Inventor Programming in C++ by Owen Ransen
(C) 2021 Owen F Ransen
for (lOccCount=1; lOccCount <= lNoOccs; ++lOccCount) {
// Get the nth occurrence... CComPtr<ComponentOccurrence> pCompOcc; Result = pOccs->get_Item(lOccCount, & pCompOcc);
//get the display name from the component occurrence CComBSTR bstrDisplayName; Result = pCompOcc->get_Name(&bstrDisplayName); TRACE("Component occurrence %02d <%s>\n",lOccCount,bstrDisplayName); // See if there are any other occurrences below the current one... CComPtr<ComponentOccurrencesEnumerator> pEnumOccurrences; Result = pCompOcc->get_SubOccurrences(&pEnumOccurrences); if (SUCCEEDED(Result) && (pEnumOccurrences->Count > 0)) { TRACE(" has %d sub occurrences\n",pEnumOccurrences->Count) ; }}
I've not placed any error checking in the previous code.
How to get the name of an occurrence.
12.130How to get the parameters of an assembly
If you have an assembly with parameters you can get hold of theparameters programatically like this:
CComPtr <AssemblyComponentDefinition> pAssCompDef ; pAssemblyDoc->get_ComponentDefinition (&pAssCompDef) ;
CComPtr <Parameters> pParams ; pAssCompDef->get_Parameters (&pParams) ;
const long ikNumParams = pParams->Count ;
TRACE (L"There are %d params in %s\n",ikNumParams,pszOccName);
for (int i = 1 ; i <= ikNumParams ; i++) { CComPtr <Parameter> pParam ;
219Programming Inventor in C++
(C) 2021 Owen F Ransen
pParams->get_Item (CComVariant(i),&pParam) ;
VARIANT VarValue ; pParam->get_Value (&VarValue) ; VarValue.dblVal ;
CComBSTR bstrParamName ; pParam->get_Name (&bstrParamName) ; TRACE (L" param %d is called %s and has a value of %.3f=\n",i,bstrParamName,VarValue.dblVal ) ; }
Notice how the parameter data is picked up inside the for loop.
If you have a part occurrence inside an assembly and want to get theparameters of that part a occurrence you can use this:
CComPtr<ComponentDefinition> pCompDef = nullptr ; hRes = pCompOcc->get_Definition (&pCompDef) ; if (FAILED(hRes) || (pCompDef == nullptr)){ return ReturnAndShowCOMError(hRes,L"ShowComponentOccurrenceParameters, get_Definition failed."); }
TRACE (L"The type of this occurrence is %d, def is %d\n",pCompOcc->GetType(),pCompDef->GetType()) ;
CComPtr<Parameters> pParams; CComQIPtr<PartComponentDefinition> pPartCompDef =pCompOcc->Definition; if (!pPartCompDef) { return (E_FAIL) ; }
if (pPartCompDef->IsiPartFactory) { TRACE (L"Is an ipart factory\n") ; }
// It is a part component definition, so we can get the // parameters of the part definition pParams = pPartCompDef->Parameters;
const long ikNumParams = pParams->Count ;
220 Autodesk Inventor Programming in C++ by Owen Ransen
(C) 2021 Owen F Ransen
TRACE (L"There are %d params in %s\n",ikNumParams,pszOccName);
for (int i = 1 ; i <= ikNumParams ; i++) { CComPtr <Parameter> pParam ; pParams->get_Item (CComVariant(i),&pParam) ;
VARIANT VarValue ; pParam->get_Value (&VarValue) ; CComBSTR bstrParamName ; pParam->get_Name (&bstrParamName) ; TRACE (L" param %d is called %s and has a value of %.3f=\n",i,bstrParamName,VarValue.dblVal ) ; }
12.131get_Item and Item, what sort of parameter?
When I need to get an item from a list, I generally use get_Item,because it crashes less, Item will throw an exception.
Here, the last two lines of code do the same thing:
CComPtr<UserParameter> pUserParam ; pUserParameters->get_Item (CComVariant(i),&pUserParam) ; pUserParam = pUserParameters->Item [i] ;
And what about the parameters? Generally it is an index, andgenerally that index starts at 1 (not 0) as the first item.
for (UINT i = 1 ; i <= ikNumModelParams ; i++) { CComPtr<ModelParameter> pModelParam ; pModelParameters->get_Item (CComVariant(i),&pModelParam);
Sometimes, if the item in the list has a text name, you can use thename in the call to get_Item. For example:
const wchar_t* const pszUserParamName = ... ... CComPtr<UserParameter> pUserParam = nullptr ; pUserParameters->get_Item(CComVariant(pszUserParamName),&pUserParam) ;
221Programming Inventor in C++
(C) 2021 Owen F Ransen
Horses for courses.
12.132Suppression and Unsuppression of features
To suppress and unsuppress features in a part simply use thefeature's suppression boolean:
pFeature->put_Suppressed(true) ;
(Suppression of parts in an assembly has a different use).
Here is a function which will suppress a named part in aPartComponentDefinition:
void SetSuppressPartFeatureByName(CComPtr<PartComponentDefinition>& pPartCompDef, const wchar_t* const pszName, const bool bSuppress) { TRACE (L"SetSuppressPartFeatureByName %s, %d\n",pszName,bSuppress) ;
// Get the list of features... CComPtr<PartFeatures> pFeaturesList ; HRESULT hRes = pPartCompDef->get_Features(&pFeaturesList) ; if (FAILED(hRes) || (pFeaturesList == nullptr)) { ShowCOMError(hRes,L"SetSuppressPartFeatureByNameget_Features failed"); return ; }
const long ikNumFeats = pFeaturesList->GetCount() ;
TRACE (L" There are %d pattern features\n",ikNumFeats) ;
bool bDone = false ;
for (long iFeat = 1 ; iFeat <= ikNumFeats ; iFeat++) { CComPtr<PartFeature> pFeature ; hRes = pFeaturesList->get_Item(CComVariant(iFeat),&pFeature) ; if (FAILED(hRes) || (pFeature == nullptr)) { ShowCOMError(hRes,L"SetSuppressPartFeatureByNameget_Item failed");
222 Autodesk Inventor Programming in C++ by Owen Ransen
(C) 2021 Owen F Ransen
return ; }
BSTR bstrName ; pFeature->get_Name (&bstrName) ;
if (_wcsicmp (bstrName,pszName) == 0) { if (bSuppress) { pFeature->put_Suppressed (VARIANT_TRUE) ; TRACE (L"Found Feature %d called %s to besuppressed\n",iFeat,bstrName) ;
} else { pFeature->put_Suppressed (VARIANT_FALSE) ; TRACE (L"Found Feature %d called %s to beunsuppressed\n",iFeat,bstrName) ; } bDone = true ; }
::SysFreeString (bstrName) ;
if (bDone) { break ; } }
if (!bDone) { TRACE (L"Could not suppress feature by name with name =<%s>\n",pszName) ; }}
Within a single RectangularPattern (or any other pattern) you canuse this fragment as a starting point.
In some circumstances Suppressed=VARIANT_FALSE will crashwhile put_Suppressed (VARIANT_FALSE) will not. A mysterywrapped inside an enigma. I always use put_Suppressed.
Note that you'll need to call Update to refresh the display:
pPartDocument->Update () ; // Like an AutoCAD regen
223Programming Inventor in C++
(C) 2021 Owen F Ransen
You cannot suppress all types of objects. You cannot, for example,suppress workpoints.
12.133Compute and Suppress from an iPart table programatically
Here's how I read a Compute/Suppress setting from an iPart table:
// Get the "Suppress" or "Compute" value from the table// returns true if Suppressedbool GetSuppressedFromiPartTableRowCell (const UINT ikCol, CComPtr<iPartTableRow> piPartRow) { wchar_t szValue[_MAX_PATH] ; GetStringFromiPartTableRowCell (szValue,_countof(szValue),ikCol,piPartRow) ;
// Since Suppress = Sopprimi and Compute = Calcola this // compare will work in both English and Italian return (szValue[0] == L'S') ;}
12.134Skipping missing components programatically
When looping over occurrences you must skip any missingcomponents, and you do it like this:
for (lOccCount=1; lOccCount <= lNoOccs; ++lOccCount){ // Get the nth occurrence... CComPtr<ComponentOccurrence> pCompOcc; hRes = pOccs->get_Item(lOccCount, &pCompOcc); if (FAILED(hRes)) { gLogger.Printf(ekErrMsg, L"Could not get acomponent in the attacco"); return false; }
if (VARIANT_TRUE == pCompOcc->ReferencedDocumentDescriptor->ReferenceMissing) {
224 Autodesk Inventor Programming in C++ by Owen Ransen
(C) 2021 Owen F Ransen
// Maybe a missing and skipped component... continue ; }
.
12.135How to open a document programatically
Here is some example code illustrating how to open a document file:
CComPtr<Documents> pDocs = nullptr ; HRESULT hRes = pInvApp->get_Documents (&pDocs) ; if (FAILED(hRes) || (pDocs == nullptr)) { ShowCOMError(hRes,L"RunTest,get_Documents failed "); return ; }
CComPtr<Document> pDoc; hRes = pDocs->Open (CComBSTR(L"C:\\PARTS\\MyPart.Ipt"),VARIANT_TRUE,&pDoc) ; if (FAILED(hRes) || (pDocs == nullptr)) { ShowCOMError(hRes,L"RunTest, Open failed "); return ; }
...
12.136Function calls in Autodesk Inventor C++ programming
Every COM C++ Inventor API method comes in 2 "flavors": 1. low level methods: that take output param as input and return
HRESULT, for example hRes = get_Item (Index,&Pointer).2. high level methods: that return the result directly and throw
exceptions, for example Pointer = GetItem (Index)
A concrete example of the difference is the visibility of workaxes:
// This "low level" version will not crash and you can lookat the success or not via hRes hRes = pWorkAxis->put_Visible (vbVisib) ; if (FAILED(hRes)) { // Show some error message if you want
225Programming Inventor in C++
(C) 2021 Owen F Ransen
}
// This "high level" version will throw and exception andcrash if something is wrong pWorkAxis->Visible = vbVisib ;
There are other functions which are high and low distinguished bywhether or not they have Method... in front of the name, high levelmethods are usually prefixed "Method".
Some examples :
HRESULT hRes = pWorkPlanesList->get_Item(CComVariant(1),&pWorkPlane) ; // low level version WorkPlanePtr pWorkPlane = pWorkPlanesList->GetItem(CComVariant(1)) ; // high level version
...and...
HRESULT hRes = pConstraintList->AddAngleConstraint(...etc...,&pAngConstraint) ; // low level version AngleConstraintPtr pAngConstraint =pConstraintList->MethodAddAngleConstraint(...etc...) ; // highlevel version
Note that with "low level" versions you often pass the address of apointer which is the "return value" of the function.
12.137Names of objects inside sketches
You cannot name objects inside sketches (sketch points and linesetc) though you can give them IDs and Attributes.
12.138COM pointers when programming AutoDesk Inventor
Here I'm paraphrasing Adam Nagy who helped me understand thisstuff.
When using COM objects like the ones provided by the Inventor COMAPI, then you have to take care of releasing the references to theobjects you retrieved. This is what CComPtr is helping you with,
226 Autodesk Inventor Programming in C++ by Owen Ransen
(C) 2021 Owen F Ransen
which is a smart-pointer and provides auto release of objects: when aCComPtr object variable goes out of scope then its destructor will becalled and there it will release the COM object it is referencing, i.e. itwill decrease the reference counter on that COM object.
Here are a couple of examples to help explain when you have toexplicitly release the object or how to reorganize your code to releasethe COM objects in time: all objects need to be released beforeCoUninitialize() is called.
If your CComPtr is declared inside a function (local variable) then itwill only be destructed - just like any other local variables - when thefunction returns, and that's when it will release the reference to theCOM object. In case of this sample function the pointer is releasedtoo late because of that:
int _tmain(int argc, TCHAR* argv[], TCHAR* envp[]){ HRESULT Result = NOERROR;
::CoInitialize(NULL);
// Access Inventor CLSID InvAppClsid; Result = CLSIDFromProgID (L"Inventor.Application", &InvAppClsid); if (FAILED(Result)) return Result;
CComPtr<IUnknown> pInvAppUnk; Result = ::GetActiveObject (InvAppClsid, NULL, &pInvAppUnk); if (FAILED (Result)) TRACE("Could not get the active Inventor instance\n");
if (FAILED(Result)) return Result;
CComPtr<Application> pInvApp; Result = pInvAppUnk->QueryInterface(__uuidof(Application), (void **) &pInvApp); if (FAILED(Result)) return Result;
::CoUninitialize();
return 0;
} // << pInvApp is only destructed now, i.e. it's only releasing the // Inventor Application object reference now, which is too late, // since CoUninitialize has already been called
227Programming Inventor in C++
(C) 2021 Owen F Ransen
One easy solution to this would be to place the code part that isinteracting with the COM objects into a separate function, so that thelocal variables will be release by the time we get to CoUninitialize():
int accessInventor(){ HRESULT Result = NOERROR;
// Access Inventor CLSID InvAppClsid; Result = CLSIDFromProgID (L"Inventor.Application", &InvAppClsid); if (FAILED(Result)) return Result;
CComPtr<IUnknown> pInvAppUnk; Result = ::GetActiveObject (InvAppClsid, NULL, &pInvAppUnk); if (FAILED (Result)) TRACE("Could not get the active Inventor instance\n"); if (FAILED(Result)) return Result;
CComPtr<Application> pInvApp; Result = pInvAppUnk->QueryInterface(__uuidof(Application), (void **) &pInvApp); if (FAILED(Result)) return Result;
return Result;}
int _tmain(int argc, TCHAR* argv[], TCHAR* envp[]){ HRESULT Result = NOERROR;
::CoInitialize(NULL);
// Access Inventor accessInventor();
// Once this function returned all its local objects have
// been destructed, and so the COM objects have also been released
::CoUninitialize();
return 0;}
Another simple solution is to create a local scope around the localvariables that ends before CoUninitialize():
228 Autodesk Inventor Programming in C++ by Owen Ransen
(C) 2021 Owen F Ransen
int _tmain(int argc, TCHAR* argv[], TCHAR* envp[]){ HRESULT Result = NOERROR;
::CoInitialize(NULL);
// Access Inventor inside a local scope created by the curly braces { CLSID InvAppClsid; Result = CLSIDFromProgID (L"Inventor.Application", &InvAppClsid); if (FAILED(Result)) return Result;
CComPtr<IUnknown> pInvAppUnk; Result = ::GetActiveObject (InvAppClsid, NULL, &pInvAppUnk); if (FAILED (Result)) TRACE(_"Could not get the active Inventor instance\n"); if (FAILED(Result)) return Result;
CComPtr<Application> pInvApp; Result = pInvAppUnk->QueryInterface(__uuidof(Application), (void **) &pInvApp);
if (FAILED(Result)) return Result;
} // << Now all the local variables have been destructed, // and so the COM objects have been released
::CoUninitialize();
return 0;}
When CComPtr is declared as a global variable then it will only bedestructed at the very end, even after the main function of theapplication has returned:
// This will only be destructed after _tmain() returned// which is too late, because by that time CoUninitialize()// has been called. So we'll have to release the COM object// it is referencing by setting it to NULL before calling// CoUninitialize()
CComPtr<Application> pInvApp;
int _tmain(int argc, TCHAR* argv[], TCHAR* envp[]){ HRESULT Result = NOERROR;
229Programming Inventor in C++
(C) 2021 Owen F Ransen
::CoInitialize(NULL);
// Access Inventor { CLSID InvAppClsid; Result = CLSIDFromProgID (L"Inventor.Application", &InvAppClsid); if (FAILED(Result)) return Result;
CComPtr<IUnknown> pInvAppUnk; Result = ::GetActiveObject (InvAppClsid, NULL, &pInvAppUnk); if (FAILED (Result)) TRACE("Could not get the active Inventor instance\n");
if (FAILED(Result)) return Result;
// In this case pInvApp is a global variable // declared outside the function Result = pInvAppUnk->QueryInterface(__uuidof(Application), (void **) &pInvApp); if (FAILED(Result)) return Result; }
// Release the referenced COM object by setting the CComPtr // object to NULL pInvApp = NULL;
::CoUninitialize();
return 0;}
See what I mean?
12.139VARIANT_BOOL
VARIANT_BOOL is a type currently defined as a short:
/* 0 == FALSE, -1 == TRUE */typedef short VARIANT_BOOL;
#define VARIANT_TRUE ((VARIANT_BOOL)-1)#define VARIANT_FALSE ((VARIANT_BOOL)0)
Here is an example
230 Autodesk Inventor Programming in C++ by Owen Ransen
(C) 2021 Owen F Ransen
if (VARIANT_TRUE == pCompOcc->ReferencedDocumentDescriptor->ReferenceMissing) { // Maybe a missing and skipped component... continue ; }
Here is an example:
VARIANT_BOOL bSuppressed =pFeaturePatternElement->GetSuppressed () ;
TRACE (L"Element %d suppressed = %d\n",iElem,bSuppressed) ;
In this case bSuppressed will show either -1 (true) or 0 (false).
You can use the predefined macros VARIANT_TRUE andVARIANT_FALSE as values.
Since VARIANT_FALSE is 0 you can use them in ifs like this:
if (p->InventorFunction()) { ...do something...}
12.140ParameterPtr and get_XCount
Some Inventor API COM functions take a ParameterPtr, even to getsimple integers, like the count in a RectangularPattern. Here is how todeclare and use the parameter pointer in those cases:
//CComPtr<Parameter> iXCount ; // this works too ParameterPtr iXCount ; pRectPattern->get_XCount (&iXCount) ;
So you can use CComPtr<Parameter> or ParameterPtr. Here is anexample of getting an integer value:
CComPtr<Parameter> XCountParam ;
231Programming Inventor in C++
(C) 2021 Owen F Ransen
pRectPatFeat->get_XCount (&XCountParam) ; const int ikXCount = XCountParam->GetValue () ;
TRACE (L"Component %d is called %s, and the x count is%d\n",iRect,bstrName,ikXCount) ;
So you need to use GetValue().
Note that you have to look at the pointers because if there is no ycount it is assumed to be 1. I assume. The following code will printout the x and y counts of a rectangular array.
CComPtr<Parameter> pXCountParam ; pRangoPattern->get_XCount (&pXCountParam) ; int iXCount = 1 ; // Init to 1 is important if (pXCountParam != nullptr) { iXCount = pXCountParam->GetValue () ; } CComPtr<Parameter> pYCountParam ; pRangoPattern->get_YCount (&pYCountParam) ; int iYCount = 1 ; // Init to 1 is important if (pYCountParam != nullptr) { iYCount = pYCountParam->GetValue () ; }
gLogger.Printf(ekLogMsg, L"Rect X count = %d Y count = %d",iXCount,iYCount);
12.141Gettings objects by name
When you create complex parts and assemblies it is best to namethem with other than the default names. That way you can get hold ofthem in your program without having to remember indices into a get_Item array, or having to remember that WorkPoint1 is the point atthe end of the tube or that WorkPlane3 is in the center of the cube.
(Note that for international programs you may prefer to use indices,because the standard objects created by Inventor change the names.For example "X Axis" in English is "Asse X" in Italian.)
232 Autodesk Inventor Programming in C++ by Owen Ransen
(C) 2021 Owen F Ransen
Here are some functions for getting hold of named objects:
bool GetSketchInPartByName (CComPtr<PlanarSketch>& pSketch, // return value ifsketch found const wchar_t* const pszSketchName, CComPtr<PartComponentDefinition>& pPartCompDef, const bool kbShowErr /*=true*/) { // Get the sketch in the part by name... HRESULT hRes = pPartCompDef->Sketches->get_Item(CComVariant(pszSketchName), &pSketch); if (FAILED(hRes)) { if (kbShowErr) { ShowCOMError (hRes,L"GetSketchByName(%s) but could not 'get'sketch\n",pszSketchName); } return false ;
} else { return true ; }}
HRESULT GetWorkPlaneByName (CComPtr<WorkPlane>& pWorkPlane, const wchar_t* constpszWorkPlaneName, CComPtr<PartComponentDefinition>&pPartCompDef) { // Get the sketch in the part by name... HRESULT hRes =pPartCompDef->WorkPlanes->get_Item(CComVariant(pszWorkPlaneName),&pWorkPlane); if (FAILED(hRes) || (pWorkPlane == nullptr)) { ShowCOMError (hRes,L"GetWorkPlaneByName but 'get'failed\n"); return (E_FAIL) ; }
return (S_OK) ;}
HRESULT GetWorkAxisByName (CComPtr<WorkAxis>& pWorkAxis, const wchar_t* const pszWorkAxisName, CComPtr<PartComponentDefinition>&pPartCompDef) {
233Programming Inventor in C++
(C) 2021 Owen F Ransen
// Get the sketch in the part by name... HRESULT hRes =pPartCompDef->WorkAxes->get_Item(CComVariant(pszWorkAxisName),&pWorkAxis); if (FAILED(hRes) || (pWorkAxis == nullptr)) { ShowCOMError (hRes,L"GetWorkAxisByName but 'get'failed\n"); return (E_FAIL) ; }
return (S_OK) ;}
You can imagine what GetWorkPointByName will look like.
Since these functions report errors you could ignore their returnvalues if you want, if there is an error you'll see it.
12.142How to get the RectangularPatterns in aPartComponentDefinition
What you need to remember is that a RectangularPattern is a feature,so you need to get the features of a part in order to get anyrectanguar patterns inside that part.
Here is a function which lists the names of rectangular patterns insidethe part parameter passed to it:
void ListRectangularPatternFeatures(CComPtr<PartComponentDefinition>& pPartCompDef){ // Get the list of features... CComPtr<PartFeatures> pFeaturesList ; pPartCompDef->get_Features(&pFeaturesList) ;
// Get the list of rectangular features, we will add to thislist.... CComPtr<RectangularPatternFeatures> pRectPatList ; pFeaturesList->get_RectangularPatternFeatures (&pRectPatList);
const long ikNumRecFeats = pRectPatList->GetCount() ;
234 Autodesk Inventor Programming in C++ by Owen Ransen
(C) 2021 Owen F Ransen
TRACE (L"There are %d rectangular pattern features\n",ikNumRecFeats) ;
for (int iRect = 1 ; iRect <= ikNumRecFeats ; iRect++) {
CComPtr <RectangularPatternFeature> pRectPatFeat ; pRectPatList->get_Item (CComVariant(iRect),&pRectPatFeat);
BSTR bstrName = pRectPatFeat->GetName () ;
TRACE (L"Component %d is called %s\n",iRect,bstrName) ;
::SysFreeString(bstrName); }}
Error checking has been removed for brevity and clarity, but, asalways, you should check the return values of the various InventorAPI functions.
How to add a RectangularPattern to a PartComponentDefinition.
12.143ResultFeatures
ResultFeatures, when got from Patterns, are workplanes, workpoints,worksurfaces which are created when the Pattern is created.
CComPtr <ObjectsEnumerator> pObjectsEnumerator ; pFeaturePatternElement->get_ResultFeatures (&pObjectsEnumerator) ; const int ikNumObj = pObjectsEnumerator->GetCount () ;
ResultFeatures are the result of creating a pattern with somefeatures. You often use them for getting proxies of the features.Result Features are of the type ObjectsEnumerator, a list of objects.
235Programming Inventor in C++
(C) 2021 Owen F Ransen
Graphically:
Here is a fragment which gets
12.144ObjectsEnumerator, a list of objects
The ObjectsEnumerator can be thought of a list of objects, from aselection set for example, or from resulting features in a pattern.
12.145Parameter types
Apart from Model parameters and User parameters each parameteralso has a type ParameterTypeEnum which specifies who and why aparameter was created.
Here is how to get the information:
ParameterTypeEnum eParamType ; pModelParam->get_ParameterType (&eParamType) ; TRACE (L"The ParameterTypeEnum is %d\n",eParamType) ;
236 Autodesk Inventor Programming in C++ by Owen Ransen
(C) 2021 Owen F Ransen
and the values can be:
kDerivedParameter : Parameters automatically created from derivedcomponent. kModelParameter : Parameter created automatically by Inventorwhen a command requires it. kReferenceParameter : Parameter created automatically by Inventorwhile creating a driven dimension, for example. kTableParameter : Parameters created from a table; like aspreadsheet. kUserParameter : Parameters explicitly created by the user.
The user units of the parameters are stored as a string and can beaccessed like this:
CComBSTR bstrUnits ; pModelParam->get_Units (&bstrUnits) ; TRACE (L"Units = <%s> \n",(wchar_t*)(bstrUnits)) ;
You'll get strings like "mm" or "in" etc. Note that internal units may bedifferent.
12.146Face Edge EdgeProxy
As far as I can tell the EdgeProxy will give you details of where theedge is in the Assembly into which the Part has been inserted.
// Get the surface bodies from the occurrence... CComPtr<SurfaceBodies> pSurfaceBodies; hRes = pThisCompOcc->get_SurfaceBodies(&pSurfaceBodies);
WalertBoxW (L"Occurrence 1 has %d surface bodies\n",pSurfaceBodies->Count);
// Get the first surface body from the component definition. // (There should only ever be one surface body.) CComPtr<SurfaceBody> pBody; hRes = pSurfaceBodies->get_Item(1, &pBody);
// Get the shells from the body. CComPtr<FaceShells> pShells; hRes = pBody->get_FaceShells(&pShells);
237Programming Inventor in C++
(C) 2021 Owen F Ransen
WalertBoxW (L"The surface body has has %d shells\n",pShells->Count) ;
// Enumerate through the shells. long shellCount = 1; CComPtr<FaceShell> pShell; for (;(hRes = pShells->get_Item(shellCount, &pShell)) == S_OK; pShell.Release()) { TRACE (L" Shell %d\n", shellCount);
// Increment the counter and print the current value. ++shellCount;
// Get the faces from the shell. CComPtr<Faces> pFaces; hRes = pShell->get_Faces(&pFaces);
// Enumerate through the faces of the current shell. long faceCount = 1; CComPtr<Face> pFace; for (;(hRes = pFaces->get_Item(faceCount, &pFace)) == S_OK;pFace.Release()) { // Increment the counter and print the current value. ++faceCount; TRACE (L" Face %d ", faceCount);
CComPtr <Edges> pEdges ; pFace->get_Edges (&pEdges) ; TRACE (" has %d edges\n",pEdges->Count) ; for (long e = 1 ; e <= pEdges->Count ; e++) { CComPtr <Edge> pEdge ; pEdges->get_Item (e,&pEdge) ;
CComQIPtr<EdgeProxy> pEdgeProxy ; pThisCompOcc->CreateGeometryProxy (pEdge,(IDispatch**)&pEdgeProxy) ;
CComPtr<Vertex> pStartVertex ; pEdgeProxy->get_StartVertex (&pStartVertex) ;
CComPtr<Point> pStartPoint ; pStartVertex->get_Point (&pStartPoint) ;
TRACE (" %.1f %.1f %.1f\n",pStartPoint->GetX(),pStartPoint->GetY(),pStartPoint->GetZ()) ; }
// Get the geometry from the face. SurfaceTypeEnum surfaceType; hRes = pFace->get_SurfaceType(&surfaceType);
switch (surfaceType) {
238 Autodesk Inventor Programming in C++ by Owen Ransen
(C) 2021 Owen F Ransen
default : TRACE (L" Unrecognised surface type:%d\n",surfaceType); break ;
case kCylinderSurface : TRACE (L" Cylindrical surface\n"); break ;
case kTorusSurface : TRACE (L" Cylindrical surface\n"); break ;
case kPlaneSurface : TRACE (L" Plane surface\n"); break ; } } }
12.147Attributes
An "Attribute" is extra data added to an Inventor object. You, theprogrammer, can store non graphical data in an object's attributes.
If you have ever programmed AutoCAD you could compare attributesin Inventor with Xdata in AutoCAD.
AutoDesk supplies a program called Attribute Helper which you canuse to add attributes into objects. For example into the faces of apart.
239Programming Inventor in C++
(C) 2021 Owen F Ransen
Imagine the cylindrical surface of the part above has some attributesets. This is how to list them programatically:
CComQIPtr<PartDocument> pPartDoc ; // will remain nullptr ifno part found
// Find the documents which are currently open... CComPtr<Documents> pDocs ; HRESULT hRes = theApp.GetInvAppPtr()->get_Documents (&pDocs); if (FAILED(hRes) || (pDocs == nullptr)) { ShowCOMError(hRes,L"CCollettore::CreateCollectorMainTubePart,get_Documents failed "); return ; }
const int ikNumDocs = pDocs->Count ;
// Get hold of the first Part doc which you find... for (int iDoc = 1 ; iDoc <= ikNumDocs ; iDoc++) {
240 Autodesk Inventor Programming in C++ by Owen Ransen
(C) 2021 Owen F Ransen
CComPtr<Document> pDocument ;
hRes = pDocs->get_Item(iDoc,&pDocument) ;
if (FAILED(hRes) || (pDocument == nullptr)) { TRACE (L"Could not get document number %d",iDoc); return ; }
TRACE (L"Got document %d of type %d%s\n",iDoc,pDocument->DocumentType, GetInventorDocTypeDesc(pDocument->DocumentType)); if (pDocument->DocumentType == kPartDocumentObject) { // Convert from the "general document" type into the"drawing document" type... pPartDoc = pDocument ; break ; // Assume there is only one } }
if (pPartDoc == nullptr) { WalertBoxA ("No part found") ; return ; }
// Get hold of the component defintion so you can look at thefaces.. CComPtr<PartComponentDefinitions> pPartCompDefs ; pPartDoc->get_ComponentDefinitions (&pPartCompDefs) ;
TRACE (" there are %d component defs\n",pPartCompDefs->Count);
CComPtr<PartComponentDefinition> pPartCompDef ; pPartCompDefs->get_Item (1,&pPartCompDef) ;
CComPtr<SurfaceBodies> pSurfaceBodies; hRes = pPartCompDef->get_SurfaceBodies(&pSurfaceBodies);
// Get the first surface body from the component definition. // (There should only ever be one surface body.) CComPtr<SurfaceBody> pBody; hRes = pSurfaceBodies->get_Item(1, &pBody);
// Get the shells from the body. CComPtr<FaceShells> pShells; hRes = pBody->get_FaceShells(&pShells);
// Enumerate through the shells. const long ikNumShells = pShells->Count;
241Programming Inventor in C++
(C) 2021 Owen F Ransen
for (long iShell = 1 ; iShell <= ikNumShells ; iShell++) { CComPtr<FaceShell> pShell; hRes = pShells->get_Item(iShell, &pShell);
TRACE (L" Shell %d\n", iShell); // Get the faces from the shell. CComPtr<Faces> pFaces; hRes = pShell->get_Faces(&pFaces);
// Enumerate through the faces of the current shell. const long ikNumFaces = pFaces->Count; for (long iFace = 1 ; iFace <= ikNumFaces ; iFace++) { CComPtr<Face> pFace; hRes = pFaces->get_Item(iFace, &pFace) ;
CComPtr <Edges> pEdges ; pFace->get_Edges (&pEdges) ;
CComPtr<AttributeSets> pFaceAttSets ; pFace->get_AttributeSets (&pFaceAttSets) ; TRACE ("Face %d has %d attributesets\n",iFace,pFaceAttSets->Count) ; // This face has at least one attribute set... if (pFaceAttSets->Count > 0) {
// Get the first attribute set... CComPtr<AttributeSet> pFaceAttSet ; pFaceAttSets->get_Item(CComVariant(1),&pFaceAttSet) ;
if (pFaceAttSet != nullptr) {
// Get the first attribute... CComPtr<Attribute> pFaceAtt ; pFaceAttSet->get_Item(CComVariant(1),&pFaceAtt) ;
// Show the user what is inside theattribute... if (pFaceAtt != nullptr) { CComBSTR cbstrName ; pFaceAtt->get_Name (&cbstrName) ;
// Get the value. Use a CComVariantbecause there are strings // and number variants... CComVariant varValue ; pFaceAtt->get_Value (&varValue) ;
// Here we assume it is a string... WalertBoxW (L"Name = <%s> Value =
242 Autodesk Inventor Programming in C++ by Owen Ransen
(C) 2021 Owen F Ransen
<%s>",cbstrName,varValue.bstrVal) ; } } } } }
12.148CreateExtrudeDefinition
This function does not actually create an extrusion, it should bepaired with Add to do that. Here is an example (error checkingremoved):
// Now at last we can use the pProfile to create a newextrusion, adding it to the list // of extruded features CComPtr<ExtrudeDefinition> pExtrudeDef; hRes = pListOfExtrusions->CreateExtrudeDefinition(pProfile,kJoinOperation,&pExtrudeDef);
pExtrudeDef->SetDistanceExtent(_variant_t(kHeight),kPositiveExtentDirection );
CComPtr<ExtrudeFeature> pExtrude; hRes = pListOfExtrusions->Add (pExtrudeDef);
What you need to remember is that an ExtrudeDefinition is not anextrusion feature.
12.149Inserting an extrusion in a Part
You need to have a part .ipt document open for the following functionto work, and that .ipt must have a sketch called Sketch1 alreadyexisting inside it. I've tested it with an empty Sketch1.
243Programming Inventor in C++
(C) 2021 Owen F Ransen
I've removed much of the hRes checking, but you should do thatchecking:
static HRESULT AddSolid(CComPtr<Application> pInvApp){ CComPtr<Document> piDoc; HRESULT hRes = pInvApp->get_ActiveDocument(&piDoc);
CComQIPtr<PartDocument> pPartDoc(piDoc); // you should checkthat pPartDoc does not result in nullptr
CComPtr<PartComponentDefinition> piPartCompDef; hRes = pPartDoc->get_ComponentDefinition(&piPartCompDef); CComPtr<TransientGeometry> oTG; hRes = pInvApp->get_TransientGeometry(&oTG);
CComPtr<Point2d> oCenterP; hRes = oTG->CreatePoint2d(0, 0, &oCenterP);
CComPtr<PlanarSketch> pSketch = NULL; hRes = piPartCompDef->Sketches->get_Item(CComVariant(_T("Sketch1")), &pSketch);
CComPtr<SketchCircle> pSketchCircle = NULL; hRes = pSketch->SketchCircles->AddByCenterRadius(oCenterP,2);
CComPtr<Profile> pProfile = NULL; CComVariant pSegs; CComVariant preserve; hRes =pSketch->Profiles->AddForSolid(VARIANT_TRUE,pSegs,preserve,&pProfile);
CComPtr<PartFeatures> pPartFs; hRes = piPartCompDef->get_Features(&pPartFs);
CComPtr<ExtrudeFeatures> pExtrudeFs; hRes = pPartFs->get_ExtrudeFeatures(&pExtrudeFs);
CComPtr<ExtrudeDefinition> pExtrudeDef; hRes = pExtrudeFs->CreateExtrudeDefinition(pProfile,kJoinOperation,&pExtrudeDef);
pExtrudeDef->SetDistanceExtent(_variant_t(2.0),
244 Autodesk Inventor Programming in C++ by Owen Ransen
(C) 2021 Owen F Ransen
kPositiveExtentDirection);
CComPtr<ExtrudeFeature> pExtrude; hRes = pExtrudeFs->Add (pExtrudeDef); if (FAILED(hRes)) { TRACE ("AddSolid but could Add ExtrudeDefinition\n"); return hRes ; }
TRACE ("AddSolid finished, extrusion added ok.\n");
return hRes;}
Good luck young man.
12.150Optional parameters and empty COM values
In VB and VBA there are sometimes optional parameters. And oftenthe only help available for functions in Inventor is the VB version, youhave to guess the parameters of the C++ version from the VBversion.
When there are optional parameters in C++ which you don't want touse you will probably have to pass an empty COM type value. A goodexample is GetTemplateFile:
hr = pFileManager->GetTemplateFile (kAssemblyDocumentObject, //type of file kDefaultSystemOfMeasure, kDefault_DraftingStandard, CComVariant(), // Optional inVB, GUID for Weld and SheetMetal &strTemplateFilename); //return value
That fourth parameter is an empty variant because we do not use it inthis instance. In the VB description of the same function it is anoptional parameter.
See also function call methods.
245Programming Inventor in C++
(C) 2021 Owen F Ransen
12.151Points and CenterPoints
The difference between these two sorts of points is that CenterPointsare displayed as center points:
Programatically the difference is here:
CComPtr<SketchPoint> pInventorPt; pSketch->SketchPoints->Add(pThePoint,VARIANT_TRUE,&pInventorPt);
That VARIANT_TRUE says "show as center point". Otherwise youshould use VARIANT_FALSE.
You can get the setting for this in two ways:
VARIANT_BOOL bHoleCenter ; pInventorPt->get_HoleCenter (&bHoleCenter) ; // first method
bHoleCenter = pInventorPt->HoleCenter ; // second method
246 Autodesk Inventor Programming in C++ by Owen Ransen
(C) 2021 Owen F Ransen
12.152GetTemplateFile
The template file is how an new empty file of a new object will looklike. It is what is used when you create a new file, and contains thingslike units etc. When you do a new part or a new assembly Inventoruses a template file to create your empty file.
You can get hold of template files for various types of documents likethis:
CComBSTR strTemplateFilename; CComPtr<FileManager> pFileManager;HRESULT hr = pInvApp->get_FileManager(&pFileManager);
hr = pFileManager->GetTemplateFile (kAssemblyDocumentObject, //type of file DocumentTypeEnum kDefaultSystemOfMeasure, kDefault_DraftingStandard, CComVariant(), // GUID forWeldment and SheetMetal &strTemplateFilename); //return value
In the above call the strTemplateFilename would come backcontaining something like this:
C:\Users\Public\Documents\Autodesk\Inventor 2013\Templates\Standard.iam
Some common values in the first parameter (a DocumentTypeEnum) of GetTemplateFile are:
kPartDocumentObject kAssemblyDocumentObject kDrawingDocumentObject
The second parameter sets the measurement units (mm or inches). Itcan be
247Programming Inventor in C++
(C) 2021 Owen F Ransen
Enumerator Value
Description
kDefaultSystemOfMeasure
8961
Installed, default system inuse for this user.
kEnglishSystemOfMeasure
8963
English system of measure(inches etc.)
kMetricSystemOfMeasure
8962
Metric system of measure(mm etc.).
Note that GetTemplateFile can have an empty 4th parameter in thiscase because we are not dealing with Weldment or SheetMetal. Inthose two cases the fourth parameter will be a GUID which furtheridentifies the sort of standard to be used.
Of course if you know and want to use a specific template file you cansimply do this:
strTemplateFilename = L"C:\\Users\\Public\\Documents\\Autodesk\\Inventor 2017\\Templates\\LuVe\\RanStd.idw" ;
without calling GetTemplateFile, and use the string in a call like this:
// create a new assembly document using an existing template file CComPtr<Document> pDocument=nullptr; hRes = pDocuments->Add(kAssemblyDocumentObject, strTemplateFilename,VARIANT_TRUE, &pDocument); if (FAILED(hRes)) { return ReturnAndShowCOMError (hRes,L"Could not make new assemblydocument"); }
12.153Add a (planar) sketch to a workplane programatically
Here is a function which will add a new sketch to a named workplanein a PartComponentDefinition:
HRESULT AddSketchToWorkplane (CComPtr<PartComponentDefinition>&pPartCompDef, const wchar_t* constpszNewSketchName, const wchar_t* const
248 Autodesk Inventor Programming in C++ by Owen Ransen
(C) 2021 Owen F Ransen
pszOldWorkPlaneName) { // Get the workplanes list CComPtr<WorkPlanes> pWorkPlaneList ; HRESULT hRes = pPartCompDef->get_WorkPlanes(&pWorkPlaneList); if (FAILED(hRes) || (pWorkPlaneList == nullptr)) { return ReturnAndShowCOMError (hRes,L"AddSketchToWorkplane, could not get workplane list") ; }
// Get the workplane to which we will add the sketch... CComPtr<WorkPlane> pWorkPlane ; hRes = pWorkPlaneList->get_Item(CComVariant(pszOldWorkPlaneName), &pWorkPlane); if (FAILED(hRes) || (pWorkPlaneList == nullptr)) { return ReturnAndShowCOMError (hRes,L"AddSketchToWorkplane, could find specific workplane") ; }
// Get the list of sketches CComPtr<PlanarSketches> pSketchList ; hRes = pPartCompDef->get_Sketches (&pSketchList); if (FAILED(hRes) || (pSketchList == nullptr)) { return ReturnAndShowCOMError (hRes,L"AddSketchToWorkplane, could not get planar sketches") ; } // Create a new sketch inside the list of sketches CComPtr<PlanarSketch> pNewSketch ; // return value offollowing call... hRes = pSketchList->Add (_variant_t((IDispatch *)pWorkPlane), VARIANT_FALSE, // Ignored when basedon a workplane &pNewSketch) ; if (FAILED(hRes) || (pNewSketch == nullptr)) { return ReturnAndShowCOMError (hRes,L"AddSketchToWorkplane, could not get planar sketches") ; }
pNewSketch->put_Name (CComBSTR (pszNewSketchName)) ;
return (S_OK) ;}
See also this page.
249Programming Inventor in C++
(C) 2021 Owen F Ransen
12.154Component Definition
A part component definition is contained inside a part document. Thecomponent definition contains the nitty gritty of the actual objects youwant to manipulate and add to. Often there are lists of components,like sketches, features, workplanes etc:
To get the PartComponentDefiniton from a PartDocument use this:
CComPtr<PartDocument> pPartDocument ; ... init pPartDocument in some way...
// Get the component definition inside the PartDoc... CComPtr<PartComponentDefinition> pPartCompDef; hRes = pPartDocument->get_ComponentDefinition(&pPartCompDef); if (FAILED(hRes) || (pPartCompDef == nullptr)) { return ReturnAndShowCOMError (hRes,L"get_ComponentDefinition failed") ;
250 Autodesk Inventor Programming in C++ by Owen Ransen
(C) 2021 Owen F Ransen
}
An AssemblyDocument and an AssemblyDocumentDefinition has thesame sort of structure. Here you can see just two of the many listsinside an AssemblyDocument:
There are other lists inside an AssemblyComponentDefinition. Here isan example of getting the AssemblyComponentDefinition and theconstraints list inside it:
// Init this in some way...... CComQIPtr<AssemblyDocument> pAssemblyDoc = pDoc ;
// Get assembly component definition
251Programming Inventor in C++
(C) 2021 Owen F Ransen
CComPtr<AssemblyComponentDefinition> pAssemblyCompDef; hRes =pAssemblyDoc->get_ComponentDefinition(&pAssemblyCompDef);
CComPtr<AssemblyConstraints> pConstraintList; hRes = pAssemblyCompDef->get_Constraints(&pConstraintList) ;
12.155Adding a workplane to a Part programatically
You need to get the list of workplanes and add to that. Here are thestandard workplanes which are contained in all parts:
As an example here I add a workplane which is offset from the YZPlane by 2.3. Here is what we will do graphicaly:
252 Autodesk Inventor Programming in C++ by Owen Ransen
(C) 2021 Owen F Ransen
// Get the list of workplanes in the part... CComPtr<WorkPlanes> pWorkPlanesList ; pPartCompDef->get_WorkPlanes (&pWorkPlanesList) ; if (FAILED(hRes) || (pWorkPlanesList == nullptr)) { return ReturnAndShowCOMError (hRes,L"CreateMainTube,could not get work planes list") ; } TRACE (L"There are %d workplanes\n",pWorkPlanesList->Count) ;
// Get the YZ Plane work plane (Index 1)... CComPtr<WorkPlane> pWorkPlane ; hRes = pWorkPlanesList->get_Item (CComVariant(1),&pWorkPlane); if (FAILED(hRes) || (pWorkPlane == nullptr)) { return ReturnAndShowCOMError (hRes,L"CreateMainTube,could not get standard workplane") ; }
// Just for fun print the name of the 1st standardworkplane... CComBSTR bstrWrkplaneName ; pWorkPlane->get_Name(&bstrWrkplaneName) ; TRACE (L"pWorkPlane(1) is called <%s>\n",bstrWrkplaneName) ; // Create a workplane parallel to the standard YZ Plane... CComPtr<WorkPlane> pOffsetWorkPlane ; hRes = pWorkPlanesList->AddByPlaneAndOffset
253Programming Inventor in C++
(C) 2021 Owen F Ransen
(_variant_t((IDispatch *)pWorkPlane), // "starting" plane CComVariant(2.3), // how much to offset VARIANT_FALSE, // See note below &pOffsetWorkPlane) ; // Return value if (FAILED(hRes) || (pOffsetWorkPlane == nullptr)) { return ReturnAndShowCOMError (hRes,L"CreateMainTube,could not add workplane with offset") ; } // For fun, again, get the name of the new workplane... hRes = pOffsetWorkPlane->get_Name (&bstrWrkplaneName) ; if (FAILED(hRes)) { return ReturnAndShowCOMError (hRes,L"CreateMainTube,could not get name of offset workplane") ; } TRACE (L"Offset WorkPlane was called <%s>\n",bstrWrkplaneName) ;
// Change the name of the workplane... pOffsetWorkPlane->put_Name (CComBSTR (L"Parallel_Smith")) ;
Note: This line in the call to AddByPlaneAndOffset...
VARIANT_FALSE, // See note below
...basically sets whether the plane is visible to the user. Theparameter is called Construction and if true then is just for theprogram to construct things and will not be visible to the user.
12.156Set the visibility of all workplanes in a part
Here is how to set all the WorkPlanes in a part to be visible orinvisible:
void SetVisibilityOfAllWorkPlanes (CComPtr<PartComponentDefinition>& pPartCompDef, const bool kbVisibility){
254 Autodesk Inventor Programming in C++ by Owen Ransen
(C) 2021 Owen F Ransen
// Get the list of workplanes in the part... CComPtr<WorkPlanes> pWorkPlanesList ; HRESULT hRes = pPartCompDef->get_WorkPlanes (&pWorkPlanesList) ; if (FAILED(hRes) || (pWorkPlanesList == nullptr)) { ShowCOMError (hRes,L"SetVisibilityOfAllWorkPlanes, could not get work planes list") ; return ; }
TRACE (L"There are %d workplanes\n",pWorkPlanesList->Count) ;
const UINT ikNumWorkPlanes = pWorkPlanesList->Count ;
VARIANT_BOOL vbVisib = kbVisibility ? VARIANT_TRUE : VARIANT_FALSE ;
for (UINT i = 1 ; i <= ikNumWorkPlanes ; i++) { CComPtr<WorkPlane> pWorkPlane ; hRes = pWorkPlanesList->get_Item(CComVariant(i),&pWorkPlane) ; if (FAILED(hRes) || (pWorkPlane == nullptr)) { ShowCOMError (hRes,L"SetVisibilityOfAllWorkPlanes, could not get item %d",i) ; return ; } pWorkPlane->Visible = vbVisib ; }}
You can write similar functions for WorkPoints and WorkAxes.
12.157Listing the names of axes in a part
Here's an example of how to do it:
for (int i = 1 ; i <= pPartCompDef->WorkAxes->Count ; i++) { CComPtr<WorkAxis> pWorkAxis ; HRESULT hRes = pPartCompDef->WorkAxes->get_Item (CComVariant(i),&pWorkAxis) ; if (FAILED(hRes)) { gLogger.Printf (ekLogMsg,L"Could not get axis number %d\n",i); } else { gLogger.Printf (ekLogMsg,L"Got axis %d, name = <%s> ",i,LPCWSTR(pWorkAxis->Name)) ; } }
Note the LPCWSTR cast.
255Programming Inventor in C++
(C) 2021 Owen F Ransen
12.158get_ActiveDocument
The active document can be one of many types. Here is an examplecall:
CComPtr<Document> pDoc;
HRESULT hRes=pApplication->get_ActiveDocument(&pDoc);
get_ActiveDocument will put NULL in pDoc if there is no documentopen. You have to check that as well as hRes:
CComPtr<Document> pDoc;HRESULT hRes = pInvApp->get_ActiveDocument(&pDoc);if (FAILED(hRes) || (pDoc == nullptr)) { ShowCOMError(hRes,L"Get Active Document Failed"); return ;}
12.159Get and Set the name of an Inventor document
You can get and set the document display name...
256 Autodesk Inventor Programming in C++ by Owen Ransen
(C) 2021 Owen F Ransen
...like this:
pPartDoc = CComQIPtr<PartDocument>(pDoc);
BSTR bstrName ; pDoc->get_DisplayName (&bstrName) ; TRACE (L"\nFull document name was %s\n",bstrName) ;
pPartDoc->DisplayName = L"George" ;
pDoc->get_DisplayName (&bstrName) ; TRACE (L"\nFull document name now is %s\n",bstrName) ;
The above also illustrates how to get a part document pointer from adocument pointer.
257Programming Inventor in C++
(C) 2021 Owen F Ransen
12.160The .AddIn file
What is the .AddIn file? The .AddIn file is an XML format file whichtells Inventor various things about your program. Inventor knowswhere to look for .AddIn files and so can pick up information aboutyour AddIn. Open an example .AddIn file to get familiar with itscontents, you'll be able to find one here:
C:\ProgramData\Autodesk\Inventor 2013\Addins
or in a directory similar.
<?xml version="1.0" encoding="utf-8"?><Addin Type="Standard"> <!--Created for Autodesk Inventor Version 17.0--> <ClassId>{213C79E5-0949-4CD8-93EA-77058D01BC48}</ClassId> <ClientId>{213C79E5-0949-4CD8-93EA-77058D01BC48}</ClientId> <DisplayName>Ch1AddInAddInServer</DisplayName> <Description>Description of Chapter 1</Description> <Assembly>C:\Users\Owen\Documents\MyAutoDeskStuff\Ch1AddIn.dll</Assembly> <LoadOnStartUp>1</LoadOnStartUp> <UserUnloadable>1</UserUnloadable> <Hidden>0</Hidden> <SupportedSoftwareVersionGreaterThan>16..</SupportedSoftwareVersionGreaterThan> <DataVersion>1</DataVersion> <UserInterfaceVersion>1</UserInterfaceVersion> </Addin>
Here are the most imports parts of an .AddIn file:
ClassId and ClientId which are simply unique identifiers to make sureInventor does not confuse your AddIn with other AddIns. DisplayName and Description are strings which will appear in theAddIn manager. (You can find the AddIn manager under the Toolstab, Options panel of the Inventor ribbon.) DisplayName appears inthe main list, and Description appears at the bottom of the dialogwhen you click on the name in the main list.
The Assembly is the path to the DLL which contains your AddIn, andso it is this entry which tells Inventor where to find your program. Ifyour DLL is in Inventor's bin directory you can simply list the name ofthe AddIn without the full path, for example: <Assembly>ScrewMaker.dll</Assembly>
258 Autodesk Inventor Programming in C++ by Owen Ransen
(C) 2021 Owen F Ransen
The UserUnloadable element specifies whether the user can unloadthe AddIn. Assumed to be true if this value is not specified (i.e. usercan unload the add-in). Value can be 0 or 1.
The optional Hidden element defines whether the AddIn is visible inthe AddIn Manager or not. A value of 1 indicates that it is hidden,although the end-user can still right-click within the AddIn Managerand choose "Show hidden members" to display all AddIns. Thedefault value is 0, i.e. not hidden.
The UserInterfaceVersion is explained here.
12.161Adding a flush constraint programatically
A flush constraint means two planes are aligned on the same plane.So this means that you must get hold of the two planes to make themflush. Imagine two boxes, you could select a face from each box tobecome flush.
Here is an example of adding a flush constraint withAddFlushConstraint. AddFlushConstraint requires WorkPlanes orplanar objects like faces. The example below uses faces (planar
259Programming Inventor in C++
(C) 2021 Owen F Ransen
objects).
When you call this function you'll need two parts (with one box ineach part) in the Inventor assembly document for this to work.
static void DoFlushConstraint (CComPtr<Application>& pInvApp){ TRACE (L"DoFlushConstraint starting\n"); CComPtr<Document> pDoc; HRESULT hRes = pInvApp->get_ActiveDocument(&pDoc); if (FAILED(hRes) || (pDoc == nullptr)) { ShowCOMError(hRes,L"Get Active Document Failed"); return ; } TRACE (L"A document is open, is it an assemply document?\n");
CComQIPtr<AssemblyDocument> pAsmDoc(pDoc); CComPtr<AssemblyComponentDefinition> pAssemblyCompDef; hRes = pAsmDoc->get_ComponentDefinition(&pAssemblyCompDef); if (FAILED(hRes) || (pAssemblyCompDef == nullptr)) { TRACE (L"Maybe this is not an assembly document?\n"); return ; }
TRACE (L"Getting occurrences, each occurrese is like an instance of a part\n");
CComPtr<ComponentOccurrences> pOccs; hRes = pAssemblyCompDef->get_Occurrences(&pOccs); long iNumOccs ; hRes = pOccs->get_Count(&iNumOccs);
if (iNumOccs != 2) { TRACE (L"This program needs exactly 2 occurrences in the assembly to work, but the doc has %d\n",iNumOccs); return ; }
// Get the list of constraints of the assembly so you can add a new one CComPtr<AssemblyConstraints> pConstraintList; hRes = pAssemblyCompDef->get_Constraints(&pConstraintList) ; if (FAILED(hRes) || (pConstraintList== nullptr)) { TRACE (L"Could not get the constraints of the assembly\n"); return ; }
TRACE (L"The assembly has %d existing constraints\n",pConstraintList->Count) ;
260 Autodesk Inventor Programming in C++ by Owen Ransen
(C) 2021 Owen F Ransen
CComPtr<Face> pFace1,pFace2; pAssemblyCompDef->Occurrences->Item[1]->SurfaceBodies->Item[1]->Faces->get_Item (1,&pFace1) ; pAssemblyCompDef->Occurrences->Item[2]->SurfaceBodies->Item[1]->Faces->get_Item (1,&pFace2) ;
if ((pFace1 == nullptr) || (pFace2 == nullptr)) { TRACE (L"Could not get two faces\n"); return ; }
CComVariant varEmpty, varReal(0.0);
// add the constraint CComPtr<FlushConstraint> pFC; hRes = pConstraintList->AddFlushConstraint(pFace1, pFace2, varReal, varEmpty, varEmpty,&pFC); if (FAILED(hRes)) { ShowCOMError (hRes,L"Could not add flush constraint\n"); return ; }
TRACE (L"Added constraint\n");}
Other sorts of constraints are available too.
12.162Adding a flush constraint using workplanes
Here is an example, which shows that you must use geometricalproxies, assuming you have a CComQIPtr<AssemblyDocument>pAsmDoc to start off with.
/* * Get the assembly definition which contains the actual"stuff"... */ CComPtr<AssemblyComponentDefinition> pAssemblyCompDef = nullptr ; hRes = pAsmDoc->get_ComponentDefinition(&pAssemblyCompDef);
/* * Get the list of occurrences so that you can add twocyliders to it... */ CComPtr<ComponentOccurrences> pOccurrencesList=nullptr; hRes = pAssemblyCompDef->get_Occurrences (&pOccurrencesList)
261Programming Inventor in C++
(C) 2021 Owen F Ransen
;
/* * Create some geometries to place the parts in space... */ CComPtr<TransientGeometry> pTransGeom = nullptr ; pInvApp->get_TransientGeometry(&pTransGeom); CComPtr<Matrix> pPosMatrix = nullptr ; hRes = pTransGeom->CreateMatrix(&pPosMatrix); // Defaults to0 0 0
CComPtr<ComponentOccurrence> pCyl1Occ = nullptr; hRes = pOccurrencesList->Add (CComBSTR(L"C:\\TEST\\Cyl1.ipt"),pPosMatrix,&pCyl1Occ) ;
CComQIPtr<PartComponentDefinition> pCyl1CompDef =CComQIPtr<PartComponentDefinition>(pCyl1Occ->Definition); CComPtr<WorkPlane> pWorkPlane1=nullptr ; hRes = pCyl1CompDef->WorkPlanes->get_Item(CComVariant(L"XYPlane"),&pWorkPlane1);
CComPtr<WorkPlaneProxy> pWPProxy1 ; pCyl1Occ->CreateGeometryProxy(pWorkPlane1,(IDispatch**)&pWPProxy1) ;
CComPtr<ComponentOccurrence> pCyl2Occ = nullptr; hRes = pOccurrencesList->Add (CComBSTR(L"C:\\TEST\\Cyl2.ipt"),pPosMatrix,&pCyl2Occ) ; CComQIPtr<PartComponentDefinition> pCyl2CompDef =CComQIPtr<PartComponentDefinition>(pCyl2Occ->Definition); CComPtr<WorkPlane> pWorkPlane2 ; hRes = pCyl2CompDef->WorkPlanes->get_Item(CComVariant(L"YZPlane"),&pWorkPlane2); CComPtr<WorkPlaneProxy> pWPProxy2 ; pCyl2Occ->CreateGeometryProxy(pWorkPlane2,(IDispatch**)&pWPProxy2) ;
// Get the list of constraints of the assembly so you can adda new one CComPtr<AssemblyConstraints> pConstraintList = nullptr ; hRes = pAssemblyCompDef->get_Constraints(&pConstraintList) ;
CComVariant varEmpty, varReal(0.0); CComPtr<FlushConstraint> pFC = nullptr ; hRes = pConstraintList->AddFlushConstraint
262 Autodesk Inventor Programming in C++ by Owen Ransen
(C) 2021 Owen F Ransen
(pWPProxy1,pWPProxy2, varEmpty,varEmpty, varEmpty,&pFC);
12.163Constraints and parts from a programmer's point of view
Inside an AssemblyDocument (or rather an AssemblyComponentDefinition) Occurrences and Constraints can beimagined like this:
You can see that occurrences of parts are "constrained" together byconstraints. "Ball" and "Chain" are constrained by the constraintnumber 1, called "Mate:1"
263Programming Inventor in C++
(C) 2021 Owen F Ransen
You can also see that constraint number 4 has a user selected name,"Hold_Me".
When you are programming it might be good to name yourconstraints so that you can easily pick the one you are looking for,rather than having to remember the indices or the standard names.
12.164Loading your DLL
Addins are loaded at the startup of Inventor.
Once you have your Inventor AddIn DLL you need to show it toInventor so it can be loaded. You do this by creating an .AddIn file. Ifyou use the wizard that will be done for you. The .addin file needs tobe placed in one or more of several directories.
One example place is here:
%ALLUSERSPROFILE%\Autodesk\Inventor 2013\Addins
Note that the above path will resolve down to something like this:
C:\ProgramData\Autodesk\Inventor 2013\Addins
Also note that maybe you are using a different version of Inventor, sothe 2013 becaomes 2014 for example.
Anyway, since the .AddIn file has a path to your DLL, Inventor scansthe known directories and examines the .AddIn files it finds. Hence itreads the <Assembly> part of the .AddIn file, and knows where topick up the file.
264 Autodesk Inventor Programming in C++ by Owen Ransen
(C) 2021 Owen F Ransen
12.165Sketches in an Inventor Part
This diagram shows you how sketches are contained inside a part:
They are inside a list which is itself inside a component definition.Programatically here is how to get a sketch by name:
// Get the component definition inside the PartDoc... CComPtr<PartComponentDefinition> pPartCompDef; hRes = pPartDoc->get_ComponentDefinition(&pPartCompDef);
// Get the sketch in the part by name... CComPtr<PlanarSketch> pSketch = NULL; hRes = pPartCompDef->Sketches->get_Item(CComVariant(L"MAIN_TUBE_CIRCS"), &pSketch); if (FAILED(hRes)) { ShowCOMError (hRes,L"AddSolid but could not 'get'sketch\n"); return (false) ; }
265Programming Inventor in C++
(C) 2021 Owen F Ransen
You can get hold of sketches by index (starting from #1)
CComPtr<PlanarSketch> pSketch ; // Get the first sketch in the part hRes = pPartCompDef->Sketches->get_Item(CComVariant(1),&pSketch);
Of course both these sketch getting methods require that the namedsketch you are looking for, or the index, are present in the Sketcheslist of the Inventor Part.
12.166Default workplanes and default sketches programatically
Every part has 3 default workplanes.
You can add sketches to them programatically using this function:
// Adds a sketch to one of the three standard workplanes in a partbool AddSketchToStdWorkplane (CComPtr<PlanarSketch>& pNewSketch, CComPtr<PartComponentDefinition>& pPartCompDef, const wchar_t* const pszNewSketchName, const UINT ikWorkPlaneNumber) // gikXIndex,gikYIndex, gikZIndex{ if ((pszNewSketchName == nullptr) || (wcslen(pszNewSketchName) == 0)) { gLogger.Printf (ekErrMsg,L"ASTSWP, workplane name incorrect") ;
266 Autodesk Inventor Programming in C++ by Owen Ransen
(C) 2021 Owen F Ransen
return false; }
CComPtr<WorkPlane> pWorkPlane; bool bOk = GetStdWorkPlaneByIndex(pWorkPlane, ikWorkPlaneNumber,pPartCompDef); if (!bOk) { return false; }
// Get the list of sketches CComPtr<PlanarSketches> pSketchList ; HRESULT hRes = pPartCompDef->get_Sketches (&pSketchList); if (FAILED(hRes)) { ShowCOMError (hRes,L"AddSketchToWorkplane, could not get planarsketches") ; return false; }
hRes = pSketchList->Add (_variant_t((IDispatch *)pWorkPlane),VARIANT_FALSE,&pNewSketch) ; if (FAILED(hRes)) { ShowCOMError (hRes,L"AddSketchToWorkplane, could not get planarsketches") ; return false; }
pNewSketch->put_Name (CComBSTR (pszNewSketchName)) ;
return true;}
The last part of the code above shows you how to get the name of asketch using get_Name. The following diagram shows the indices toget the standard workplanes:
267Programming Inventor in C++
(C) 2021 Owen F Ransen
You can also use: gikXIndex, gikYIndex, gikZIndex
This code...
// Create a part CComPtr<PartDocument> pPartDoc; bool bOk = CreateNewPart(GetInvAppPtr(),pPartDoc,L"Test"); if (!bOk) { return; }
CComPtr<PartComponentDefinition> pPartDef; HRESULT hRes = pPartDoc->get_ComponentDefinition(&pPartDef); if (FAILED(hRes) || (pPartDef==nullptr)) { return; }
for (UINT i = gikXIndex; i <= gikZIndex; i++) { // Add a sketch CString kcsSketchName; kcsSketchName.Format(L"Sketch%d", i); CComPtr<PlanarSketch> pNewSketch; AddSketchToStdWorkplane(pNewSketch, pPartDef, kcsSketchName, i); AddCircleToSketch(pNewSketch, i * 1, i * 2, i * 3); }
...creates these three sketches...
268 Autodesk Inventor Programming in C++ by Owen Ransen
(C) 2021 Owen F Ransen
See also this page.
12.167Add a work point at a sketch point
Here's a function to place a workpoint in space at the same positionas a point in a sketch. This is what we want to do:
269Programming Inventor in C++
(C) 2021 Owen F Ransen
This is how to do it:
HRESULT AddWorkPointAtSketchPoint(CComPtr<PartComponentDefinition>& pPartCompDef, const wchar_t* constpszNewPointName, const wchar_t* constpszSketchName) /*Adds a workpoint in space at the first point in a named sketch*/{ CComPtr<WorkPoints> pWorkPointsList ; HRESULT hRes = pPartCompDef->get_WorkPoints(&pWorkPointsList) ; if (FAILED(hRes) || (pWorkPointsList == nullptr)) { return ReturnAndShowCOMError (hRes,L"AddWorkPointAtSketchPoint, could not get workplane list") ; }
CComPtr<PlanarSketch> pSketch ;
270 Autodesk Inventor Programming in C++ by Owen Ransen
(C) 2021 Owen F Ransen
hRes = GetSketchByName (pSketch,pszSketchName,pPartCompDef) ; if (FAILED(hRes) || (pSketch == nullptr)) { return ReturnAndShowCOMError (hRes,L"AddWorkPointAtSketchPoint, could not get sketch") ; }
CComPtr<SketchPoints> pSkPoints; pSketch->get_SketchPoints (&pSkPoints) ; long iNumPoints ; hRes = pSkPoints->get_Count (&iNumPoints) ; if (FAILED(hRes) || (iNumPoints < 1)) { return ReturnAndShowCOMError (hRes,L"AddWorkPointAtSketchPoint, not enough points in sketc") ; }
CComPtr<SketchPoint> pSketchPoint ; hRes = pSkPoints->get_Item (1,&pSketchPoint) ; if (FAILED(hRes) || (pSketchPoint == nullptr)) { return ReturnAndShowCOMError (hRes,L"AddWorkPointAtSketchPoint, get sketch point failed") ; }
CComPtr<WorkPoint> pWorkPoint ; hRes = pWorkPointsList->AddByPoint (_variant_t((IDispatch*)pSketchPoint),VARIANT_FALSE,&pWorkPoint) ; if (FAILED(hRes) || (pWorkPoint == nullptr)) { return ReturnAndShowCOMError (hRes,L"AddWorkPointAtSketchPoint, Add workpoint failed") ; }
pWorkPoint->put_Name (CComBSTR (pszNewPointName)) ;
return (hRes) ;}
This function assumes that there is at least 1 points in the sketch, andtakes the first. The function also takes a name for the workpointbecause I find that giving signifigant names to objects in Inventor makes them easier to find.
271Programming Inventor in C++
(C) 2021 Owen F Ransen
12.168Getting and setting the sketch name (as well as other objects)
Here is how to get and set the sketch (and other objects) name:
CComPtr<PlanarSketch> pSketch; ... CComBSTR bstrSketchName ; pSketch->get_Name (&bstrSketchName) ; //Get the sketch name ... pSketch->put_Name (CComBSTR(L"Tube_Base")) ; // Set the name
Many many objects in the Inventor API have names, like workplanesand parts etc. You can usually interrogate and change the nameswith the methods shown above.
12.169PatternSpacingTypeEnum
Constants identifying the pattern spacing type, used in, patterns(arrays) of objects.
Name Value Description
kDefault 33537Occurrences separated by specified
distance.
kFitted 33538All occurrences fitted within specified
distance.kFitToPathLe
ngth33539 All occurrences fitted within path length.
12.170PatternOrientationEnum
PatternOrientationEnum, Constants identifying the pattern orientationmethod.
Name Value Description
kAdjustToDirection1 33794Orientation of occurrences adjustedto direction 1.
272 Autodesk Inventor Programming in C++ by Owen Ransen
(C) 2021 Owen F Ransen
kAdjustToDirection2 33795Orientation of occurrences adjustedto direction 2.
kIdentical 33793All occurrences are orientedidentically.
12.171Occurences as Xrefs
If you are familiar with Xrefs in AutoCAD then you can imagine thatan occurrence can be considered as a sort of xref.
As Xiaodong Liang of Autodesk said:
"I think this is a good comparison. The Inventor assembly containsthe occurrence information (file, path, transformation etc) only. Itdoes not contain the geometry of the occurrence. When the assemblyis opened, it tries to resolve the occurrence, after that, read thegeometries and display them in the assembly context with thetransformation defined with the occurrence. The occurrence isactually a proxy of the original document. If the original file cannot befound, Inventor will ask the user to resolve. So it may be OK to saysome behaviors are similar to Xref."
12.172VT_I4
VT_I4 – 32-Bit signed long value (positive 2147483647 to negative2147483648 )
12.173rgs file for Inventor AddIns, what is it?
***WARNING***: The old plugin wizard may create this file for you,but it is no longer required for modern registry free AddIns.
12.174BSTR OLECHAR wchar_t
BSTR is normally defined as an OLECHAR* and is normally a pointerto a wide string.
So this is valid:
CComBSTR bstrSketchName ;
273Programming Inventor in C++
(C) 2021 Owen F Ransen
pSketch->get_Name (&bstrSketchName) ; TRACE (L"The name of the sketch just made is %s\n",bstrSketchName) ;
Remember that with TRACE the format specifier requires L toindicate wide char string types (wchar_t). See here for anotherexample.
CComBSTR is a class which encapsulates BSTR:
class CComBSTR{public:
BSTR m_str;......
Here's an example of going from CComBSTR to CString:
BSTR bstrThisUserParamName ; pUserParam->get_Name(&bstrThisUserParamName); const CString kcsThisParamName(bstrThisUserParamName);
So use CComBSTR instead of BSTR whenever you can, since BSTRrequires more explicit memory handling, a call to ::SysFreeString afteruse for example:
BSTR DisplayName; HRESULT hr = pSketch->get_Name(&DisplayName); ... do things... ::SysFreeString(DisplayName);
As an aside I doubt that anyone is still using ASCII, almost allInventor programmers are using UNICODE. For that reason I nolonger use the _T macro, which was used to conditionally compile forboth ASCII and UNICODE.
You of course have to check what type of string a given function isrequesting. In case of calling Inventor API functions the strings arerequired as BSTR (sometimes wrapped in a VARIANT) which you canget in multiple ways. All of them can create it from wchar_t:SysAllocString, CComBSTR, _bstr_t
274 Autodesk Inventor Programming in C++ by Owen Ransen
(C) 2021 Owen F Ransen
Here is how to get a CString from a _bstr_t.
_bstr_t FullName (pPartCompDef->iPartMember->GetReferencedFile()->GetFullFileName()); const CString kcsFulName((wchar_t*)FullName);
12.175AddForSolid
AddForSolid creates a profile inside a sketch which can be used forextrusion (for example).
CComPtr<Profile> pProfile = NULL;CComVariant pSegs;CComVariant pReserve;pSketch->Profiles->AddForSolid (VARIANT_TRUE, // combine allelements into one "path" pSegs, // path segments,may well not be used pReserve, // not used, butparameter requitred &pProfile); // returnedcombined profile
The VARIANT_TRUE means combine all the elements in the sketchinto one path.
pSegs may well not be used.
In the above case pProfile is the return data from AddForSolid.pProfile could be used later in the function like this:
CComPtr<ExtrudeDefinition> pExtrudeDef;hRes =pExtrudeFs->CreateExtrudeDefinition(pProfile,PartFeatureOperationEnum::kJoinOperation,&pExtrudeDef);
275Programming Inventor in C++
(C) 2021 Owen F Ransen
Next...
12.176VBA, VB.NET, C# or C++
VBA is only recommended for small macros.
VB can create quite large programs, as can C#.
C++ can be used to create EXE files which interact with Inventor from"outside" Inventor.
C++ can be used to create DLLs which run "inside" Inventor and addcommands to the program and icons in the "Ribbon".
12.177Profiles in sketches programatically
A profile is something like a circle, which is contained inside a sketch.
You can get the list of profiles in a sketch like this:
// Get Profiles CComPtr<Profiles> pSkProfiles; hr = pSketch->get_Profiles(&pSkProfiles) ;
12.178Creating an Assembly
HRESULT CreateNewAssembly (CComQIPtr<AssemblyDocument>& pAssemblyDoc, CComPtr<AssemblyComponentDefinition>&pAssemblyCompDef, const CString& kcsTemplateFile)/*Create a new assembly and return the document and assembly componentdefinition.AssemblyComponentDefinition is a list of parts and constraints.*/{ CComPtr<Documents> pDocuments=nullptr; HRESULT hRes = pInvApp->get_Documents (&pDocuments) ; if (FAILED(hRes)) { return ReturnAndShowCOMError (hRes,L"CreateNewAssembly, could not getdocuments");
276 Autodesk Inventor Programming in C++ by Owen Ransen
(C) 2021 Owen F Ransen
}
CComBSTR strTemplateFilename(kcsTemplateFile);
// create a new assembly document using the template passed to us CComPtr<Document> pDocument=nullptr; hRes = pDocuments->Add(kAssemblyDocumentObject, strTemplateFilename,VARIANT_TRUE, &pDocument); if (FAILED(hRes)) { return ReturnAndShowCOMError (hRes,L"CreateNewAssembly, Could not makenew assembly document"); }
// Try to cast to an assembly document, this should not ever fail... pAssemblyDoc = pDocument ;
// Get hold of the assembly component definition too... pAssemblyCompDef = nullptr ; hRes = pAssemblyDoc->get_ComponentDefinition(&pAssemblyCompDef); if (FAILED(hRes)) { return ReturnAndShowCOMError (hRes,L"CreateNewAssembly, Could not gethold of assembly component definition"); }
//theApp.PrintfLedMessage (RGB(255,255,155),CCT_DLG,L"Assieme OK...") ;
return S_OK ;}
Here is another example of how to do it in C++
static void CreateAssembly (const CComPtr<Application>& pInvApp) { CComPtr<Documents> pDocuments; pInvApp->get_Documents (&pDocuments) ;
CComBSTR strTemplateFilename; // Get assembly document template CComPtr<FileManager> pFileManager; HRESULT hr = pInvApp->get_FileManager(&pFileManager); if (FAILED(hr)) { TRACE (_"Could not get file manager\n"); return ; }
hr = pFileManager->GetTemplateFile(kAssemblyDocumentObject, kDefaultSystemOfMeasure, kDefault_DraftingStandard, CComVariant(), &strTemplateFilename); if (FAILED(hr)) { TRACE ("Could not get template file\n"); return ;
277Programming Inventor in C++
(C) 2021 Owen F Ransen
}
TRACE ("Template file is:\n%s\n",strTemplateFilename);
// create a new assembly document from a standard template CComPtr<Document> pDocument; hr = pDocuments->Add(kAssemblyDocumentObject, strTemplateFilename, VARIANT_TRUE, &pDocument); if (FAILED(hr)) { TRACE ("Could not create new assembly document\n"); return ; }
CComPtr<TransientGeometry> pTransGeom; hr = pInvApp->get_TransientGeometry(&pTransGeom); if (FAILED(hr)) { TRACE ("Could not get transient geometry\n"); return ; }
CComPtr<Matrix> pMatrix; hr = pTransGeom->CreateMatrix(&pMatrix); if (FAILED(hr)) { TRACE ("Could not create matrix\n"); return ; }
CComBSTR csFileName = L"c:\\temp\\cylinder.ipt" ;
// Try to cast to the document to an assembly document CComQIPtr<AssemblyDocument> pAssemblyDoc = pDocument ; if (!pAssemblyDoc) { TRACE ("Could not get assembly doc\n"); return ; }
// Get assembly component definition CComPtr<AssemblyComponentDefinition> pAssemblyCompDef; hr = pAssemblyDoc->get_ComponentDefinition(&pAssemblyCompDef); if (FAILED(hr)) { TRACE ("Could not get assembly component definition\n"); return ; }
// Get the ComponentOccurrences collection for the assembly document CComPtr<ComponentOccurrences> pOccs; hr = pAssemblyCompDef->get_Occurrences(&pOccs); if (FAILED(hr)) { TRACE ("Could not get assembly occurrences\n"); return ;
278 Autodesk Inventor Programming in C++ by Owen Ransen
(C) 2021 Owen F Ransen
}
CComPtr<ComponentOccurrence> pOcc1; hr = pOccs->Add(csFileName,pMatrix,&pOcc1) ; if (FAILED(hr)) { TRACE ("Could not add assembly occurrence 1\n"); return ; }
CComPtr<Vector> pVector; hr = pTransGeom->CreateVector(20,2,2,&pVector); if (FAILED(hr)) { TRACE ("Could not create vector\n"); return ; } pMatrix->SetTranslation (pVector,VARIANT_TRUE) ; CComPtr<ComponentOccurrence> pOcc2; hr = pOccs->Add(csFileName,pMatrix,&pOcc2) ; if (FAILED(hr)) { TRACE ("Could not add assembly occurrence 2\n"); return ; }
CComPtr<Face> pCylFace1 = GetCylinderSurface (pOcc1) ; CComPtr<Face> pCylFace2 = GetCylinderSurface (pOcc2) ;
TRACE ("pCylFace1 = %p pCylFace2 = %p\n",pCylFace1,pCylFace2);}
Of course if you know and want to use a specific template file you cansimply do this:
strTemplateFilename = L"C:\\Users\\Public\\Documents\\Autodesk\\Inventor 2013\\Templates\\LuVe\\RanStd.iam" ;
without calling GetTemplateFile .
See also creating a drawing, DWG IDW.
12.179Getting the project file location and other options programatically
You can use this fragment:
CComPtr<FileLocations> pFileLocations;Result = pInvApp->get_FileLocations(&pFileLocations);if (SUCCEEDED(Result))
279Programming Inventor in C++
(C) 2021 Owen F Ransen
{CComBSTR bstrFileLocationsFile;Result =
pFileLocations->get_FileLocationsFile(&bstrFileLocationsFile);if (SUCCEEDED(Result))
TRACE(L"Active Project File: %ls \n",bstrFileLocationsFile);
}
and something like this:
static HRESULT GetInventorInformation(CComPtr<Application>&pInvApp){ // Display some information about Inventor
TRACE("\nInventor Information: \n");
CComBSTR bstrCaption;HRESULT Result = pInvApp->get_Caption(&bstrCaption);if (SUCCEEDED(Result))
TRACE(L"Caption: %ls \n", bstrCaption);
CComBSTR bstrLanguage;Result = pInvApp->get_LanguageName(&bstrLanguage);if (SUCCEEDED(Result))
TRACE(L"Language: %ls \n", bstrLanguage);
CComBSTR bstrUserName;Result = pInvApp->get_UserName(&bstrUserName);if (SUCCEEDED(Result))
TRACE(L"User Name: %ls \n", bstrUserName);
CComPtr<SoftwareVersion> pSoftwareVersion;Result = pInvApp->get_SoftwareVersion(&pSoftwareVersion);if (SUCCEEDED(Result)){
CComBSTR bstrSoftVerDispName;Result =
pSoftwareVersion->get_DisplayName(&bstrSoftVerDispName);if (SUCCEEDED(Result))
TRACE(L"Software Version: %ls \n",bstrSoftVerDispName);
}
280 Autodesk Inventor Programming in C++ by Owen Ransen
(C) 2021 Owen F Ransen
CComPtr<FileLocations> pFileLocations;Result = pInvApp->get_FileLocations(&pFileLocations);if (SUCCEEDED(Result)){
CComBSTR bstrFileLocationsFile;Result =
pFileLocations->get_FileLocationsFile(&bstrFileLocationsFile);if (SUCCEEDED(Result))
TRACE(L"Active Project File: %ls \n",bstrFileLocationsFile);
}
CComPtr<GeneralOptions> pGeneralOptions;Result = pInvApp->get_GeneralOptions(&pGeneralOptions);if (SUCCEEDED(Result)){
CComBSTR bstrStartupProjectFile;Result =
pGeneralOptions->get_StartupProjectFileName(&bstrStartupProjectFile);
if (SUCCEEDED(Result))TRACE(L"Startup Project File: %ls \n\n",
bstrStartupProjectFile);}
// Obtain the 'Visible' property of the active application VARIANT_BOOL bVisible = VARIANT_FALSE; Result = pInvApp->get_Visible(&bVisible); if (FAILED(Result)) return Result;
if (bVisible != VARIANT_TRUE){
pInvApp->Visible = VARIANT_TRUE ; }
CComPtr<Document> pDoc; Result = pInvApp->get_ActiveDocument(&pDoc); if (FAILED(Result)) { ShowCOMError (Result,L"get_ActiveDocument failed\n") ; return Result ; }
...etc.
281Programming Inventor in C++
(C) 2021 Owen F Ransen
12.180regsvr32
This information is only useful if you are making old style AddIns.New Registry Free AddIns don't require the use of regsvr32.
Required for when you make AddIns. Two examples:
regsvr32 shmedia.dll (for registering a file)
regsvr32 /u shmedia.dll (for unregistering a file)
Note that the full path of the .dll may be used to ensure that you areregistering the correct dll.
The def file is required because it is used to export the functionsDllRegisterServer and DllUnregisterServer. Here's an example:
; SimpleAddIn.def : Declares the module parameters.
LIBRARY "SimpleAddIn.DLL"
EXPORTSDllCanUnloadNow PRIVATEDllGetClassObject PRIVATEDllRegisterServer PRIVATEDllUnregisterServer PRIVATE
DllCanUnloadNow is a function inside your code which Inventor callsto see if it can unload the DLL to free up memory.
12.181What and where is the AddIn manager?
You can get hold of it here:
282 Autodesk Inventor Programming in C++ by Owen Ransen
(C) 2021 Owen F Ransen
But also from the Windows Start Menu->Programs->Autodesk->Inventor->Tools. Just look for the "+" icon.
In your .AddIn file you can put a description of the addin which willappear in the manager:
You can also see the DisplayName from the .AddIn file in the main listof the manager. In this case it is InventorAddIn5AddInServer.
12.182RxInventor.tlb
A tlb file is a type-library and it contains a description of one or more aCOM components.
283Programming Inventor in C++
(C) 2021 Owen F Ransen
It will be inside the InventorUtils.h file, something like this:
#import "RxInventor.tlb" no_namespace named_guids raw_dispinterfacesraw_method_prefix("") high_method_prefix("Method") \
rename("DeleteFile", "APIDeleteFile"), rename("CopyFile", "APICopyFile"), rename("MoveFile", "APIMoveFile") \
rename("SetEnvironmentVariable", "APISetEnvironmentVariable")
To get the compiler to find the tlb file you need to add a path to it inthe projects properties. Of these two I've been told to use the oneunder bin32 :
C:\Program Files\Autodesk\Inventor 2017\BinC:\Program Files\Autodesk\Inventor 2017\Bin\Bin32
If you don't add the path you'll get something like this:
C1083: Cannot open type library file: 'RxInventor.tlb': No such fileor directory.
The compiler will create two more files, in your DEBUG andRELEASE directories:
RxInventor.tliRxInventor.tlh
If you change Inventor version you should
1. Clean your whole solution.2. Make sure the include paths are updated.3. Erase the tli and tlh files before recompiling (in your project Debug
and Release directories).4. Search in all text files for "Inventor 2017" (if for example you are
moving from "Inventor 2017" to "Inventor 2019") and change to thenew version (in this example "Inventor 2019")
This COM/TLB/TLH/TLI stuff is all a mystery inside an enigma. Tocomplete the porting in one instance I had to change a line inside"InventorUtils.h" from...
#import "RxInventor.tlb" no_namespace named_guids...
...to...
284 Autodesk Inventor Programming in C++ by Owen Ransen
(C) 2021 Owen F Ransen
#import "C:\Program Files\Autodesk\Inventor 2019\Bin\RxInventor.tlb"no_namespace named_guids...
...else the compiler could not find the file.
12.183Adding a rectangle to a sketch programatically
We create a rectangle in a 2D sketch by specifying 2 points. You getthe points from transient geometry object, but they need to be used tocreate the two SketchPoint things.
// Get the transient geometry object. We'll use this tocreate pure geometric points CComPtr<TransientGeometry> pTrGeom; pTrGeom = pApp->TransientGeometry;
// Draw a 4cm x 3cm rectangle with the corner at (0,0) CComPtr<Point2d> pPt1; // Pure geometric point hr = pTrGeom->CreatePoint2d(0.0,0.0,&pPt1); if (FAILED(hr)) return ReturnAndShowCOMError (hr,L" create 2d pointfailed") ;
CComPtr<Point2d> pPt2; // Pure geometric point hr = pTrGeom->CreatePoint2d(4.0,3.0,&pPt2); if (FAILED(hr)) return ReturnAndShowCOMError (hr,L" create 2d pointfailed") ;
// Create sketch points from above points // Get list of SketchPoints, points existing in a sketch
285Programming Inventor in C++
(C) 2021 Owen F Ransen
CComPtr<SketchPoints> pSkPoints; hr = pSketch->get_SketchPoints(&pSkPoints); if (FAILED(hr)) return ReturnAndShowCOMError (hr,L" get sketch point listfailed") ;
// Create a SketchPoint from a geometric point CComPtr<SketchPoint> pSpt1; hr = pSkPoints->Add(pPt1, // geometrical point VARIANT_FALSE, // not a hole center &pSpt1); // resulting SketchPoint if (FAILED(hr)) return ReturnAndShowCOMError (hr,L" add point to sketchfailed") ;
CComPtr<SketchPoint> pSpt2; hr = pSkPoints->Add(pPt2,VARIANT_FALSE,&pSpt2); if (FAILED(hr)) return ReturnAndShowCOMError (hr,L" add point to sketchfailed") ;
CComPtr<SketchEntitiesEnumerator> pRectangleLines;
// Get SketchLines CComPtr<SketchLines> pSkLines; hr = pSketch->get_SketchLines(&pSkLines); if (FAILED(hr)) return ReturnAndShowCOMError (hr,L" get lines listfailed") ;
TRACE (L"There are currently %d lines in the sketch\n",pSkLines->Count) ;
// Creat a rectangle from two points hr = pSkLines->AddAsTwoPointRectangle(_variant_t((IDispatch*)pSpt1), _variant_t((IDispatch*)pSpt2), &pRectangleLines);
286 Autodesk Inventor Programming in C++ by Owen Ransen
(C) 2021 Owen F Ransen
12.184get_ and Get ?
What is the difference between the functions like these:
// High syntax version Get... ComponentOccurrencesPtr pActOccs=ActDef->GetOccurrences() ; // I suggest you avoid using this version
// Raw syntax version get_... CComPtr<ComponentOccurrences> pOccs; pAssemblyCompDef->get_Occurrences(&pOccs); // I suggest you use this version
GetProperty and MethodMethName(): is called “high” method syntax get_property and MethodName(): is the “raw” syntax.
The first one returns a value and can throw exceptions. The secondone returns an error code and take the return value as in/out param.This is usually the suggested way to use the API, reason is that yourprogram is less likely to crash in case you are not handlingexceptions.
The returned property value itself is of course identical using one orthe other syntax.
Using the second method also means that you generally do not haveto worry about Releasing smart pointers and other COM arcania...
See also VARIANT and CComVariant.
12.185UserInterfaceVersion
UserInterfaceVersion is an entry in an .AddIn file.
It is used by Inventor to know when it should regenerate the GUI ofyour .AddIn. As you develop your AddIn's GUI this number should beincremeted so that Inventor knows to recreate that part of the ribbon.
It should be a positive integer. Here's an example:
<UserInterfaceVersion>1</UserInterfaceVersion>
287Programming Inventor in C++
(C) 2021 Owen F Ransen
And if you change the GUI then you can do this:
<UserInterfaceVersion>2</UserInterfaceVersion>
to let Inventor know.
12.186Difference between CComPtr and CComQIPtr?
CComQIPtr is derived from CComPtr. QI stands for Query Interface.When you construct with a CComQIPtr it can result in nullptr., whichmeans the cast has not worked. This is useful to check the type of thepointer. For example:
CComQIPtr<PartDocument> pPartDoc(pDoc) ; if (pPartDoc == nullptr) { // pDoc did not point to a PartDocument return (false) ; }
...and another example...
CComQIPtr<AssemblyDocument> pAsmDoc(pDoc); if (pAsmDoc == nullptr) { // pDoc did not point to an AssemblyDocument return (nullptr) ; }
.
12.187VARIANT and CComVariant
CComVariant is a C++ encapsulation of VARIANT.
They are more or less tagged unions.
An example of using CComVariant when programming in Inventor isin the many get_Item calls in for loops:
const int ikNumConstraints = pConstraintList->Count ;
288 Autodesk Inventor Programming in C++ by Owen Ransen
(C) 2021 Owen F Ransen
for (int j = 1 ; j <= ikNumConstraints ; j++) { CComPtr<AssemblyConstraint> pConstraint; hRes = pConstraintList->get_Item(CComVariant(j),&pConstraint) ; if (FAILED(hRes)) { TRACE (L"Could not get the constraint %d of theassembly, hr=%X\n",j,hRes); return ; }
TRACE (L"Got constraint %d\n",j); }
Look at that CComVariant(j) call. That is how you send an integer toget_Item when get_Item wants a VARIANT.
Note also that it all the get_Item things start at 1.
You can create an empty variant and a real double variant asillustrated below:
CComVariant varEmpty, varReal(0.0);
Or you can use a global constant empty variant like this.
12.188Getting items from collections
You often want to get hold of items in various collections withinInventor objects. You can often use get_Item to do this.
CComPtr<PlanarSketch> pSketch = NULL; hRes = piPartCompDef->Sketches->get_Item(CComVariant(_T("BaseCircles")), &pSketch);
The above code looks inside the list of sketches to find the one called"BaseCircles".
Sometimes you can simply pass an index:
CComPtr<DrawingView> pThisView ; hRes = pViews->get_Item(1,&pThisView) ;
289Programming Inventor in C++
(C) 2021 Owen F Ransen
Another way of getting an item from a collection uses get_Item withan cast index:
for (int j = 1 ; j <= ikNumConstraints ; j++) { CComPtr<AssemblyConstraint> pConstraint; pConstraintList->get_Item(CComVariant(j),&pConstraint) ; TRACE ("Got constraint %d\n"),j);}
In the example above the index is passed as a CComVariant, CComVariant(j).
Here are some other ways of using get_Item:
get_Item(COleVariant(CGID)...
get_Item(CComVariant(j),... // i is an integer
get_Item(_variant_t(3L, VT_I4),... // 3 as a VT_I4
When using integer indices they always start from 1 (not 0).
12.189Assembly.Document Assembly
Here's how to get it...
CComPtr<Document> pDoc;HRESULT Result = pInvApp->get_ActiveDocument(&pDoc);if ((FAILED(iRes) || (pDoc == NULL)) { TRACE ("No document is open"); return Result ;}
// Try to cast the if (CComQIPtr<AssemblyDocument> pAssemblyDoc = pDoc){ TRACE ("This is an assembly\n");}
...basically you check to see if the cast (in red) returns somethingother than nullptr.
290 Autodesk Inventor Programming in C++ by Owen Ransen
(C) 2021 Owen F Ransen
12.19064bit vs 32bit
You should use 64 bit compilation when doing an AddIn for 64 bitInventor.
But you can use 32 or 64 bit when doing an external exe which willcommunicate with 64 bit Inventor.
12.191Client Graphics
Client Graphics are graphics which appear in drawings or on objectswhich a programmer can add via the API. There is a C++ example ofthis in the samples.
12.192Hierarchy of objects
The hierarchy is like this:
AssemblyAssemblyComponentDefinition
AssemblyConstraints...ComponentOccurencesList
ComponentOccurenceSurfaceBodiesList
SurfaceBodyFacesList
Face (Planar, Cylinder,Spheric...)
EdgeLoop (Line, Arc,Curve, Spline...)
291Programming Inventor in C++
(C) 2021 Owen F Ransen
12.193Getting or running an Inventor Instance
This code runs Inventor if it is not already running:
CLSID InvAppClsid; HRESULT Result = CLSIDFromProgID (L"Inventor.Application", &InvAppClsid); if (FAILED(Result)) return Result;
// See if Inventor is already running... CComPtr<IUnknown> pInvAppUnk; Result = ::GetActiveObject (InvAppClsid, NULL, &pInvAppUnk); if (FAILED (Result)) { // Inventor is not already running, so try to start it... TRACE (L"Could not get hold of an active Inventor , will start a new session\n"); Result = CoCreateInstance (InvAppClsid, NULL, CLSCTX_LOCAL_SERVER, __uuidof(IUnknown), (void **) &pInvAppUnk); if (FAILED (Result)){ TRACE (L"*** Failed to create a new Inventor application ***\n"); return Result; } }
CComPtr<Application> pInvApp; Result = pInvAppUnk->QueryInterface (__uuidof(Application), (void **) &pInvApp); if (FAILED(Result)) return Result;
After that you can carry on an interact with Inventor with pInvApp.
How to correct it if CLSIDFromProgID fails.
12.194Add a part to an assembly programatically
Here is a function for creating a new assembly:
// Create a new assembly and return the document and assemblycomponent definition.// AssemblyComponentDefinition is a list of parts andconstraints.bool CreateNewAssembly (CComQIPtr<AssemblyDocument>& pAssemblyDoc, CComPtr<AssemblyComponentDefinition>&pAssemblyCompDef,
292 Autodesk Inventor Programming in C++ by Owen Ransen
(C) 2021 Owen F Ransen
const CString& kcsTemplateFile){ CComPtr<Documents> pDocuments=nullptr; HRESULT hRes = pInvApp->get_Documents (&pDocuments) ; if (FAILED(hRes)) { ShowCOMError(ekErrMsg,hRes,L"CreateNewAssembly, could notget documents"); return false ; }
CComBSTR strTemplateFilename(kcsTemplateFile);
// create a new assembly document from a standard template CComPtr<Document> pDocument=nullptr; hRes = pDocuments->Add(kAssemblyDocumentObject,strTemplateFilename, VARIANT_TRUE, &pDocument); if (FAILED(hRes)) { gLogger.Printf(ekLogMsg, L"Errore in CreateNewAssemplytemplate = <%s>", kcsTemplateFile.GetString()); ShowCOMError(ekErrMsg,hRes,L"CreateNewAssembly, Could notmake new assembly document"); return false ; }
// Try to cast to an assembly document, this should not everfail... pAssemblyDoc = pDocument ;
// Get hold of the assembly component definition too... pAssemblyCompDef = nullptr ; hRes = pAssemblyDoc->get_ComponentDefinition(&pAssemblyCompDef); if (FAILED(hRes)) { ShowCOMError(ekErrMsg,hRes,L"CreateNewAssembly, Could notget hold of assembly component definition"); return false ; }
return true ;}
And here is how the above function is used:
CComQIPtr<AssemblyDocument> pAssemblyDoc ; CComPtr<AssemblyComponentDefinition> pAssemblyCompDef;
293Programming Inventor in C++
(C) 2021 Owen F Ransen
const bool kbAsmOk = CreateNewAssembly(pAssemblyDoc,pAssemblyCompDef,theApp.GetLuveIAMTemplate()) ; if (!kbAsmOk) { theApp.PrintfLedMessage (RGB(255,0,0),CCT_DLG,L"Erroredurante creazione IAM...") ; return false; }
Here is the code to do this and add a part, with no error checking:
static void CreateAssembly (const CComPtr<Application>& pInvApp) { // Get the list of documents currently in Inventor... CComPtr<Documents> pDocuments; pInvApp->get_Documents (&pDocuments) ;
// Get assembly document template, what is used as a default for .iam files // To do that you need to get the file manager CComPtr<FileManager> pFileManager; HRESULT hr = pInvApp->get_FileManager(&pFileManager);
// So get hold of the user's default template file... CComBSTR strTemplateFilename; hr = pFileManager->GetTemplateFile(kAssemblyDocumentObject, kDefaultSystemOfMeasure, kDefault_DraftingStandard, CComVariant(), &strTemplateFilename);
// Create a new assembly document from a standard template CComPtr<Document> pDocument; // This is a return value from the following call hr = pDocuments->Add(kAssemblyDocumentObject, strTemplateFilename, VARIANT_TRUE, &pDocument);
// New need some transient geometry to add in a part... CComPtr<TransientGeometry> pTransGeom; hr = pInvApp->get_TransientGeometry(&pTransGeom);
// Create a matrix CComPtr<Matrix> pMatrix; hr = pTransGeom->CreateMatrix(&pMatrix);
// This part must exist, because we are going to add an occurrence (instance) of it // to the assemply document CComBSTR csFileName = L"c:\\temp\\cylinder.ipt" ;
// Convert pDocument (returned by the call to Add previously) into an assembly document CComQIPtr<AssemblyDocument> pAssemblyDoc = pDocument ;
294 Autodesk Inventor Programming in C++ by Owen Ransen
(C) 2021 Owen F Ransen
// Get the assembly component definition CComPtr<AssemblyComponentDefinition> pAssemblyCompDef; hr = pAssemblyDoc->get_ComponentDefinition(&pAssemblyCompDef);
// Get the ComponentOccurrences collection for the assembly document CComPtr<ComponentOccurrences> pOccs; hr = pAssemblyCompDef->get_Occurrences(&pOccs);
// Now we can add an occurrence (instance) of cylinder.ipt into the assembly... CComPtr<ComponentOccurrence> pOcc1; hr = pOccs->Add(csFileName,pMatrix,&pOcc1) ;}
It is long winded but clear.
12.195Coordinates of a WorkAxis
Once you have the proxy of a work axis you can get details (in centimeters cm) like this
CComPtr<WorkAxisProxy> pWAProxy ; pTuboOcc->CreateGeometryProxy (pWAxis,(IDispatch**)&pWAProxy) ;
// Get the geometry of the axis.. LinePtr pLine = pWAProxy->GetLine() ; UnitVectorPtr pDir = pLine->Direction ;
// You can get hold of the double values like this... TRACE ("direction %.3f, %.3f, %.3f,\n",pDir->GetX(),pDir->GetY(),pDir->GetZ())
Here is another example when you have a collection of workaxes...
for (int i = 1 ; i <= pWAProxyCollection->Count ; i++) { CComPtr<WorkAxisProxy> pWAProxy; pWAProxyCollection->get_Item(i,(IDispatch**)&pWAProxy) ;
LinePtr pLine = pWAProxy->GetLine() ; UnitVectorPtr pProxyDir = pLine->Direction ; PointPtr pProxyOrigin = pLine->RootPoint ;
gLogger.Printf (ekLogMsg,"%2d origin = %.1fcm %.1fcm %.1fcm direction %.3f, %.3f, %.3f,\n", i, pProxyOrigin->X,pProxyOrigin->Y,pProxyOrigin->Z, pProxyDir->GetX(),pProxyDir->GetY(),pProxyDir->GetZ()) ; }
See also this.
295Programming Inventor in C++
(C) 2021 Owen F Ransen
12.196Invisibilize components in a collection
Here's an example of making a collection of work axes invisible. Usethe Visible attribute:
void InvisibilizeWorkAxes (CComPtr<ObjectCollection> pWACollection) { for (int i = 1 ; i <= pWACollection->Count ; i++) { CComPtr<WorkAxisProxy> pProxy ; pWACollection->get_Item (i,(IDispatch**)&pProxy) ; pProxy->Visible = VARIANT_FALSE ; // or VARIANT_TRUE }}
12.197Delete a WorkAxis
Here's some code which I have used
{ csAxisName.Format (L"WAZR%d",iRango) ; CComPtr<WorkAxis> pZWorkAxis ; HRESULT hRes = GetWorkAxisByName (pZWorkAxis,csAxisName,pNodesDef) ; if (FAILED(hRes) || (pZWorkAxis == nullptr)) { TRACE (L"DUR, could not get z axis to delete, R%d",iRango) ; return ; } pZWorkAxis->Delete(VARIANT_TRUE) ; // the parameter means "retain dependents" }
You can use the Delete function on other object types.
12.198Add a plane by offset from another plane
Note that in theory these two functions work, but currenty in Inventor2015, you cannot add planes programatically inside assemblies. Forthat use the function at the very end of this page.
static bool CreateSketchOffsetFromXYPlane (CComPtr<PlanarSketch>&pNewSketch, // The sketch created, output CComPtr<WorkPlanes>pWorkPlanes, // Where the sketch added
296 Autodesk Inventor Programming in C++ by Owen Ransen
(C) 2021 Owen F Ransen
CComPtr<PlanarSketches> pSketches, // The list to we add sketch const double kOffset, // How far to offset const wchar_t* constpszSketchName) // Name of the newsketch{ // Get hold of one of the WorkPlanes. Valid indices are 1L 2L3L for standard workplanes CComPtr<WorkPlane> pXYWorkPlane ; HRESULT hRes = pWorkPlanes->get_Item(_variant_t(3L,VT_I4),&pXYWorkPlane); if (FAILED(hRes) || (pXYWorkPlane == nullptr)) { ShowCOMError (hRes,L"CXYPOS, get_Item (workplane)failed") ; return false ; }
// Create a workplane parallel to the standard XY Plane... CComPtr<WorkPlane> pOffsetWorkPlane ; hRes = pWorkPlanes->AddByPlaneAndOffset(_variant_t((IDispatch *)pXYWorkPlane), // "starting" plane CComVariant(kOffset), // how much to offset VARIANT_TRUE, // Construction &pOffsetWorkPlane) ;// Return value
if (FAILED(hRes) || (pOffsetWorkPlane == nullptr)) { ShowCOMError (hRes,L"CXYPOS, could not add workplane withoffset, pOffsetWorkPlane=%p",pOffsetWorkPlane) ; return false ; }
// Now actually create a sketch and get a pointer to it inone go... hRes = pSketches->Add (_variant_t((IDispatch*)pOffsetWorkPlane), VARIANT_FALSE, &pNewSketch); if (FAILED(hRes)) { ShowCOMError (hRes,L"CXYPOS, AddSketch failed") ; return false ; }
pNewSketch->put_Name (CComBSTR (pszSketchName)) ;
CComBSTR bstrSketchName ; pNewSketch->get_Name (&bstrSketchName) ;
TRACE (L"The sketch is now called %s\n",bstrSketchName) ;
297Programming Inventor in C++
(C) 2021 Owen F Ransen
return true ;}
/**************************************************************************************************/
bool CreateSketchOffsetFromXYPlaneInPart(CComPtr<PartComponentDefinition>& pPartComponentDefinition, //where the sketch will be added CComPtr<PlanarSketch>&pNewSketch, // The sketch created, an output const double kOffset, const wchar_t* constpszSketchName) // Name of the newly created sketch{ // Get PlanarSketches, the list of sketches CComPtr<PlanarSketches> pSketches ; HRESULT hRes =pPartComponentDefinition->get_Sketches(&pSketches); if (FAILED(hRes) || (pSketches == nullptr)) { ShowCOMError (hRes,L"CreateXYPlaneSketch, get_Sketchesfailed") ; return false ; }
// Get standard default WorkPlanes, probably 3 only initiallyin the list CComPtr<WorkPlanes> pWorkPlanes ; hRes =pPartComponentDefinition->get_WorkPlanes(&pWorkPlanes); if (FAILED(hRes) || (pWorkPlanes == nullptr)) { ShowCOMError (hRes,L"CreateXYPlaneSketch, get_WorkPlanesfailed") ; return false ; }
bool bOk = CreateSketchOffsetFromXYPlane (pNewSketch, //The sketch created, an output pWorkPlanes, //Where the sketch will be added pSketches, //List to which we must add the sketch kOffset, //How far to offset pszSketchName) ; // Name of the newly created sketch
return bOk ;}
/*************************************************************************************************/
298 Autodesk Inventor Programming in C++ by Owen Ransen
(C) 2021 Owen F Ransen
bool CreateSketchOffsetFromXYPlaneInAsm(CComPtr<AssemblyComponentDefinition>& pAsmCompDef, // where thesketch will be added CComPtr<PlanarSketch>&pNewSketch, // The sketch created, an output const double kOffset, const wchar_t* constpszSketchName) // Name of the newly created sketch{ // Get PlanarSketches, the list of sketches CComPtr<PlanarSketches> pSketches ; HRESULT hRes = pAsmCompDef->get_Sketches(&pSketches); if (FAILED(hRes) || (pSketches == nullptr)) { ShowCOMError (hRes,L"CXYPOSIA, get_Sketches failed") ; return false ; }
// Get standard default WorkPlanes, probably 3 only initiallyin the list CComPtr<WorkPlanes> pWorkPlanes ; hRes = pAsmCompDef->get_WorkPlanes(&pWorkPlanes); if (FAILED(hRes) || (pWorkPlanes == nullptr)) { ShowCOMError (hRes,L"CXYPOSIA, get_WorkPlanes failed") ; return false ; }
bool bOk = CreateSketchOffsetFromXYPlane (pNewSketch, //The sketch created, an output pWorkPlanes, //Where the sketch will be added pSketches, //list to which we must add the sketch kOffset, //How far to offset pszSketchName) ; // Name of the newly created sketch
return bOk ;}
/*************************************************************************************************/
Here is a function which will work in assemblies:
bool CreateSketchOffsetFromXYPlaneInAsm (CComPtr<AssemblyComponentDefinition>& pAsmCompDef, // where the sketch will be added CComPtr<PlanarSketch>& pNewSketch, // The sketch created, an output const double kOffsetMm, const wchar_t* const pszSketchName) // Name of the newly created sketch{ // Get PlanarSketches, the list of sketches CComPtr<PlanarSketches> pSketches ;
299Programming Inventor in C++
(C) 2021 Owen F Ransen
HRESULT hRes = pAsmCompDef->get_Sketches(&pSketches); if (FAILED(hRes) || (pSketches == nullptr)) { ShowCOMError (hRes,L"CXYPOSIA, get_Sketches failed") ; return false ; }
// Get standard default WorkPlanes, probably 3 only initially in the list CComPtr<WorkPlanes> pWorkPlanes ; hRes = pAsmCompDef->get_WorkPlanes(&pWorkPlanes); if (FAILED(hRes) || (pWorkPlanes == nullptr)) { ShowCOMError (hRes,L"CXYPOSIA, get_WorkPlanes failed") ; return false ; }
// Get hold of one of the WorkPlanes. Valid indices are 1L 2L 3L for standard workplanes CComPtr<WorkPlane> pXYWorkPlane ; hRes = pWorkPlanes->get_Item(_variant_t(3L, VT_I4),&pXYWorkPlane); if (FAILED(hRes) || (pXYWorkPlane == nullptr)) { ShowCOMError (hRes,L"CXYPOSIA, get_Item (workplane) failed") ; return false ; }
CComPtr<TransientGeometry> pTransGeom = GetTransGeomPtr () ; CComPtr<Point> pOrigin ; hRes = pTransGeom->CreatePoint (0,0,0,&pOrigin);
CComPtr<UnitVector> UnitXVector ; pTransGeom->CreateUnitVector (1.0,0,0,&UnitXVector) ;
CComPtr<UnitVector> UnitYVector ; pTransGeom->CreateUnitVector (0.0,1.0,0,&UnitYVector) ;
// Internally Inventor always uses cm, so convert... const double kOffsetInCm = kOffsetMm/10.0 ; pOrigin->PutZ (kOffsetInCm) ; CComPtr<WorkPlane> pOffsetWorkPlane ; hRes = pWorkPlanes->AddFixed(pOrigin,UnitXVector,UnitYVector,VARIANT_FALSE,&pOffsetWorkPlane) ; if (pOffsetWorkPlane == nullptr) { TRACE (L"CXYPOSIA, Could not AddFixed") ; return false ; }
// Now actually create a sketch and get a pointer to it in one go... hRes = pSketches->Add (_variant_t((IDispatch *)pOffsetWorkPlane), VARIANT_FALSE, &pNewSketch); if (FAILED(hRes)) { ShowCOMError (hRes,L"CXYPOSIA, AddSketch failed") ; return false ; }
pNewSketch->put_Name (BSTR(pszSketchName)) ;
300 Autodesk Inventor Programming in C++ by Owen Ransen
(C) 2021 Owen F Ransen
return true ;}
12.199Getting hold of the surfaces and faces of a solid object
You can start with an occurrence, then drill down to the data you areinterested in:
1. Start with an occurrence.2. Get the surface body(ies) of the occurrence. There should only
ever be 13. Get the list of shells from the (single) surface body.4. For every shell in the list get the Faces.5. For every Face you can find out what it is.
Here are the sort of surfaces that you can find:
kCylinderSurface kPlaneSurfacekConeSurfacekSphereSurfacekTorusSurfacekBSplineSurface
In the end a cylinder is composed of a single shell which is composedof two plane surfaces and a cylindrical surface.
And here is a code fragment illustrating the process:
// Get the surface bodies from the occurrence...CComPtr<SurfaceBodies> pSurfaceBodies;hr = pOcc1->get_SurfaceBodies(&pSurfaceBodies);
TRACE (L"Occurrence 1 has %d surface bodies\n",pSurfaceBodies->Count);
// Get the first surface body from the component definition.// (There should only ever be one surface body.)CComPtr<SurfaceBody> pBody;hr = pSurfaceBodies->get_Item(1, &pBody);
301Programming Inventor in C++
(C) 2021 Owen F Ransen
// Get the shells from the body.CComPtr<FaceShells> pShells;hr = pBody->get_FaceShells(&pShells);
TRACE ("The surface body has has %d shells\n",pShells->Count) ;
// Enumerate through the shells.long shellCount = 1;CComPtr<FaceShell> pShell;for (;(hr = pShells->get_Item(shellCount, &pShell)) == S_OK; pShell.Release()){ TRACE (L" Shell %d\n", shellCount);
// Increment the counter and print the current value. ++shellCount;
// Get the faces from the shell. CComPtr<Faces> pFaces; hr = pShell->get_Faces(&pFaces);
// Enumerate through the faces of the current shell. long faceCount = 1; CComPtr<Face> pFace; for (;(hr = pFaces->get_Item(faceCount, &pFace)) == S_OK;pFace.Release()) { // Increment the counter and print the current value. ++faceCount; TRACE (L" Face %d ", faceCount);
// Get the geometry from the face. SurfaceTypeEnum surfaceType; hr = pFace->get_SurfaceType(&surfaceType);
switch (surfaceType) { default : TRACE (L" Unrecognised surface type:%d\n",surfaceType); break ;
case kCylinderSurface : TRACE (L" Cylindrical surface\n"); break ;
case kPlaneSurface : TRACE (L" Plane surface\n"); break ; } }}
302 Autodesk Inventor Programming in C++ by Owen Ransen
(C) 2021 Owen F Ransen
12.200Adding an AngleConstraint
Here's what I use:
bool AddAngleConstraintOfTwoWorkAxisProxies (CComPtr<AssemblyComponentDefinition>& pAsmCompDef, CComPtr<WorkAxisProxy>& pWAProxyA, CComPtr<WorkAxisProxy>& pWAProxyB, const double kRadsAngle) { // Get the list of constraints of the assembly so you can add a new one CComPtr<AssemblyConstraints> pConstraintList ; HRESULT hRes = pAsmCompDef->get_Constraints(&pConstraintList) ; if (FAILED(hRes) || (pConstraintList == nullptr)) { ShowCOMError (hRes,L"AddAngleConstraintOfTwoWorkAxisProxies could not get constraints.") ; return false ; }
CComVariant varReal(kRadsAngle); CComPtr<AngleConstraint> pAngleConstraint ; hRes = pConstraintList->AddAngleConstraint(pWAProxyA, pWAProxyB, varReal, kDirectedSolution, gkvarEmpty, gkvarEmpty, gkvarEmpty, &pAngleConstraint); if ((FAILED(hRes) || (pAngleConstraint == nullptr))) { ShowCOMError (hRes,L"AngleConstraint failed") ; return false ; }
return true ;}
12.201Creating a 64 bit plugin using the Wizard
1. Select new project and select Autodesk Inventor AddIn.2. Follow all the defaults til you get an empty 32 bit project3. Go to Configuration Manager Release/Debug combo in the tool bar
and select New4. Then in the dialogh which comes up select, under the Active
solution Platforms select New5. Choose x64 in the litlle dialog which pops up6. Now the first project in the list will default to WIN32, change it to
x647. Build it
303Programming Inventor in C++
(C) 2021 Owen F Ransen
You may well get 2 warnings and 1 error. The error could MSB3073,be that it cannot copy the .addin file into the Inventor addins directory,This is usually because the .addins directory in the makefile does notcontain the string 2013. For example this is wrong:
"C:\ProgramData\Autodesk\Inventor Addins\"
It should be:
"C:\ProgramData\Autodesk\Inventor 2013\Addins"
So you'll have to change that in the command line of the post buildevent step.
12.202Purging Material Assets
If you use the code on this page you may get a list where partdocuments seem to have two materials:
1 material asset type 99073 has display name <Copper - Satin>fixed name <Metal-022> and category name <Metal>2 material asset type 99073 has display name <Default> fixed name<InvGen-071> and category name <Miscellaneous>3 material asset type 99074 has display name <Copper> fixed name<MaterialInv_013> and category name <Metal>4 material asset type 99074 has display name <Generic> fixed name<MaterialInv_072> and category name <Misc>
In the above example you have, for the same part, two 99073 linesand two 99074 lines. You can get rid of these by purging the materialsin the part:
304 Autodesk Inventor Programming in C++ by Owen Ransen
(C) 2021 Owen F Ransen
12.203View orientations
The various orientation enumerator values (in ViewOrientationTypeEnum) correspond directly to the cube iconwhich shows the view orientation.
For example:
307Programming Inventor in C++
(C) 2021 Owen F Ransen
12.204Functions for project files .IPT
Here's a function which will get the currect active project file:
CString GetActiveDesignProject (){ CComPtr<DesignProjectManager> pManager; theApp.GetInvAppPtr()->get_DesignProjectManager (&pManager) ;
CComPtr<DesignProject> pDesignProject ; pManager->get_ActiveDesignProject (&pDesignProject) ;
BSTR bstrDesignProjectName ; pDesignProject->get_FullFileName (&bstrDesignProjectName) ;
return CString (bstrDesignProjectName) ;}
Notice that it also illustrates converting from a BSTR to a CString.
Here's a function (with lots of internal checks) for setting the currentactive project:
void SetActiveProject(const CString& kcsFullProjName){ // Check to make sure a document isn't open. if (GetNumDocummentsOpenInInventor() > 0) { TRACE (L"SAP but some documents are still open\n") ; return ; }
if (!FileExists (kcsFullProjName)) { TRACE (L"SAP %s but file does not exist",kcsFullProjName) ; return ; }
CComPtr<DesignProjectManager> pManager; HRESULT hRes =theApp.GetInvAppPtr()->get_DesignProjectManager (&pManager) ; if (FAILED(hRes)) { TRACE (L"SAP %s get_DesignProjectManager failed",kcsFullProjName) ; return ; }
// Get the list of all projects... CComPtr<DesignProjects> pProjectList ; hRes = pManager->get_DesignProjects (&pProjectList) ; if (FAILED(hRes)) { TRACE (L"SAP %s get_DesignProjects failed",kcsFullProjName) ;
308 Autodesk Inventor Programming in C++ by Owen Ransen
(C) 2021 Owen F Ransen
return ; }
// This assumes that the project file exists... CComPtr<DesignProject> pDesignProject ; CComBSTR bstrFullProjectName (kcsFullProjName) ; hRes = pProjectList->get_ItemByName (bstrFullProjectName,&pDesignProject) ; if (FAILED(hRes)) { TRACE (L"SAP %s get_ItemByName failed",kcsFullProjName) ; return ; }
// Make the project the active one... hRes = pDesignProject->Activate (FALSE) ; if (FAILED(hRes)) { TRACE (L"SAP %s Activate failed",kcsFullProjName) ; return ; }
// Check that the change has actually happened... if (GetActiveDesignProject().CompareNoCase(kcsFullProjName) != 0) { TRACE (L"SAP tried to activate <%s>\n" L"but active project is still <%s>", kcsFullProjName, GetActiveDesignProject()) ; }}
The above also shows to how get a CComBSTR from a CString.
309Programming Inventor in C++
(C) 2021 Owen F Ransen
12.205Listing RevolveFeatures of a part programatically
Here's a code fragment to do that:
{ gLogger.Printf (ekLogMsg,L"Object has %d features",pTroncCompDef->Features->Count) ; CComPtr<RevolveFeatures> pRevFeats = pTroncCompDef->Features->RevolveFeatures ; gLogger.Printf (ekLogMsg,L"Tronchetto has %d revolved features",pRevFeats->Count) ; for (long f = 1; f <= pRevFeats->Count; f++) { CComPtr<RevolveFeature> pFeat ; pRevFeats->get_Item (CComVariant(f),&pFeat) ; CComQIPtr<WorkAxis> pAxis = pFeat->GetAxisEntity() ; LinePtr pLine = pAxis->GetLine() ; gLogger.Printf (ekLogMsg," Origin = %.2f %.2f %.2f ",pLine->RootPoint->X,pLine->RootPoint->Y,pLine->RootPoint->Z) ; } }
Enter topic text here.
12.206Create a rectangular pattern of parts programatically
Here is an example. Remember that occurrences are "links to parts"inside an assembly:
bool CreateYArrayOfParts (CComPtr<ComponentOccurrences> pOccurrencesList, // The occurrences in the assembly CComPtr<AssemblyComponentDefinition> pCctsAssemblyCompDef, // def of the assembly CComPtr<ComponentOccurrence> pObjOcc, const double kDeltaYMm, const UINT ikCount) { CComPtr<OccurrencePatterns> pOccPatterns ; pOccPatterns = pCctsAssemblyCompDef->GetOccurrencePatterns(); if (pOccPatterns == nullptr) { gLogger.Printf(ekErrMsg, "GetOccurrencePatterns failed"); return false; }
CComPtr<TransientObjects> pTransientObjects = GetTransientObjectsPtr() ;
CComVariant varObjEnumerator; CComPtr<ObjectCollection> pObjectCollection; HRESULT hRes = pTransientObjects->CreateObjectCollection(varObjEnumerator, &pObjectCollection); if (FAILED(hRes)) { gLogger.Printf(ekErrMsg, "CreateObjectCollection failed"); return false; }
// Add the part which is the basis to the pattern... hRes = pObjectCollection->Add (pObjOcc) ; if (FAILED(hRes)) { gLogger.Printf(ekErrMsg, "Add to ObjectCollection failed"); return false;
310 Autodesk Inventor Programming in C++ by Owen Ransen
(C) 2021 Owen F Ransen
}
// Get hold of the y axis... CComPtr<WorkAxis> pYWorkAxis ; GetAsmWorkAxisByName (pYWorkAxis,L"Y Axis",pCctsAssemblyCompDef) ; if (FAILED(hRes)) { gLogger.Printf(ekErrMsg, "Could not get assembly y axis"); return false; }
pOccPatterns->AddRectangularPattern(pObjectCollection, _variant_t((IDispatch *)pYWorkAxis), VARIANT_FALSE, CComVariant(kDeltaYMm/10.0), //ColumnOffset As Variant, CComVariant(ikCount), // ColumnCount As Variant, CComVariant(), // [RowEntity] As Variant, VARIANT_TRUE, // [RowEntityNaturalDirection] As Boolean, CComVariant(0.0),// [RowOffset] As Variant, CComVariant(1)); // [RowCount] As Variant)
return (hRes == S_OK) ;}
You could make it more general.
See also suppression of occurrences in a pattern.
12.207Suppression and Unsuppression of elements in a pattern
Read about general suppression programatically first, if you have'talready.
Within a single RectangularPattern (or any other pattern) you can usethis fragment as a starting point for suppressing individual featureswithin a pattern. Note that the first element in a pattern cannot besuppressed.
CComPtr<Parameter> XCountParam ; pRectPatFeat->get_XCount (&XCountParam) ; const int ikXCount = XCountParam->GetValue () ;
TRACE (L"Component %d is called %s, and the x count is %d",iRect,bstrName,ikXCount) ;
CComPtr<FeaturePatternElements> pFeaturePatternElements ; pRectPatFeat->get_PatternElements(&pFeaturePatternElements) ;
311Programming Inventor in C++
(C) 2021 Owen F Ransen
const int ikNumElements =pFeaturePatternElements->GetCount() ; TRACE (L", this has %d FeaturePatternElements\n",ikNumElements) ;
// Start at 2 because the first element cannot besuppressed for (int iElem = 2 ; iElem <= ikNumElements ; iElem++) { CComPtr<FeaturePatternElement> pFeaturePatternElement; pFeaturePatternElements->get_Item(iElem,&pFeaturePatternElement) ;
VARIANT_BOOL bSuppressed ;
if (((iElem/2)*2) == iElem) { bSuppressed = VARIANT_TRUE ;
} else { bSuppressed = VARIANT_FALSE ; }
pFeaturePatternElement->put_Suppressed(bSuppressed); }
::SysFreeString(bstrName); }
Note that you'll need to call Update to refresh the display:
pPartDocument->Update () ; // Like an AutoCAD regen
12.208Accessing mass properties
You can access the mass properties of a Part or Assembly like this(no error checking):
CComPtr<MassProperties> pMassProps; pAssemblyCompDef->get_MassProperties(&pMassProps); double Mass; pMassProps->get_Mass(&Mass);
312 Autodesk Inventor Programming in C++ by Owen Ransen
(C) 2021 Owen F Ransen
gLogger.Printf(ekLogMsg, L"Mass = %.3f", Mass);
12.209Is Excel installed on your computer?
Here's a function which will tell you if Excel is installed on yourcomputer. You need Excel if you use Inventor tabular iParts.
bool ExcelIsPresent ()/*This looks very simply to see if Excel is installed*/{ CLSID ExcelClsid; HRESULT hRes = CLSIDFromProgID (L"Excel.Application", &ExcelClsid); if (FAILED(hRes)) { return false ;
} else { return true ; }}
12.210ConnectToInventor
This function establishes a connection from your program to theInventor application and API:
bool ConnectToInventor () { CLSID InvAppClsid; HRESULT hRes = CLSIDFromProgID (L"Inventor.Application", &InvAppClsid); if (FAILED(hRes)) { pInvApp = nullptr ; ShowCOMError (hRes,L"ConnectToInventor, CLSIDFromProgID failed, adminvs normal user conflict?") ; return false; }
// See if Inventor is already running... CComPtr<IUnknown>pInvAppUnk = nullptr ; hRes = ::GetActiveObject (InvAppClsid, NULL, &pInvAppUnk); if (FAILED (hRes)) { // Inventor is not already running, so try to start it... const int ikAnswer = YesNoBoxW (L"Inventor non sta girando, lolancio?") ; if (ikAnswer == IDNO) { return false ; }
313Programming Inventor in C++
(C) 2021 Owen F Ransen
hRes = CoCreateInstance (InvAppClsid, NULL, CLSCTX_LOCAL_SERVER,__uuidof(IUnknown), (void **) &pInvAppUnk); if (FAILED (hRes)){ pInvApp = nullptr ; ShowCOMError (hRes,L"ConnectToInventor,CoCreateInstance failed") ; return false; } }
// Get the pointer to the Inventor application... hRes = pInvAppUnk->QueryInterface (__uuidof(Application), (void **)&pInvApp); if (FAILED(hRes)) { ShowCOMError (hRes,L"ConnectToInventor,QueryInterface failed") ; return false; }
MakeInventorVisible () ;
return true ;}
12.211gLogger
I use a class called CLogger. I use it to have a printf type function to alog file. Here is an example of its use:
gLogger.Printf(ekLogMsg, L"Template file is <%s>\n", CString(sTemplate));
In your own programs you can replace it with TRACE or maybe yourown logger.
I don't include its source here because it uses other functions in otherlibraries, and it all gets too complicated.
314 Autodesk Inventor Programming in C++ by Owen Ransen
(C) 2021 Owen F Ransen
12.212iProperties programatically
12.212.1iProperties overview
iProperties are values which are stored within the Inventor document.So they are not stored within the part or assembly, but in thedocument which contains that part or assembly:
You can see iProperties by
1. Right clicking on the file (an .IPT or .IAM) and choosing iPropertiesfrom the context menu which pops up.
2. Opening the file inside Inventor and using the File menu.
316 Autodesk Inventor Programming in C++ by Owen Ransen
(C) 2021 Owen F Ransen
Custom iProperties are useful for saving data which is not directlygeometrical, maybe the date of the order or the name of the customerfor whom the part was made, etc etc.
To get the property to be visible in the dialog box you need to savethem in the "Inventor User Defined Properties" iProperty set, thisis illustrated in this function.
To be able to read a custom property you can use this function.
You can add properties which are invisible to the dialog by inventingyour own property set, as shown here.
You can list all the property sets and properties with this function.
12.212.2Listing iProperties of an Inventor document
This will list the iProperties of an Inventor document:
// iProperties listing function. Needs a DOC not a PART or ASSEMBLYvoid ListIProperties(CComPtr<Document>& pInventorDoc){ CComPtr <PropertySets> pPropSets; pInventorDoc->get_PropertySets(&pPropSets);
const long ikNumSets = pPropSets->Count;
// There are several sets of properties, loop over the sets... for (long iSet = 1; iSet <= ikNumSets; iSet++) { CComPtr<PropertySet> pPropSet; pPropSets->get_Item(CComVariant(iSet), &pPropSet);
CComBSTR bstrPropSetName; pPropSet->get_Name(&bstrPropSetName); CString csPropSetName(bstrPropSetName);
// Loop over the properties of this property set... const long ikNumProps = pPropSet->Count;
for (long iProp = 1; iProp <= ikNumProps; iProp++) { CComPtr<Property> pThisProp; pPropSet->get_Item(CComVariant(iProp), &pThisProp);
317Programming Inventor in C++
(C) 2021 Owen F Ransen
_bstr_t bstrPropName = pThisProp->GetDisplayName();
CString csPropName(bstrPropName.GetBSTR());
CComVariant varValue; pThisProp->get_Value(&varValue);
// Add more VT_... values for more detail... CString csValue; if (varValue.vt == VT_BSTR) { csValue = CString(varValue.bstrVal);
} else if (varValue.vt == VT_I4) { csValue.Format(L"%d", varValue.intVal);
} else { csValue.Format(L"vt=%d", varValue.vt); }
gLogger.Printf(ekLogMsg, L"<%s> %03d %s value=%s", csPropSetName,iProp, csPropName, csValue); } }}
You can check for different values of varValue.vt to see different typesof properties.
You'll get an output something like this:
<Design Tracking Properties> 044 FlatPatternExtentsWidth value=vt=5<Design Tracking Properties> 045 FlatPatternExtentsLength value=vt=5<Design Tracking Properties> 046 FlatPatternExtentsArea value=vt=5<Design Tracking Properties> 047 SheetMetalRule value=<Design Tracking Properties> 048 LastUpdatedWith value=2017(Build 210142000, 142)<Design Tracking Properties> 049 SheetMetalWidth value=<Design Tracking Properties> 050 SheetMetalLength value=<Design Tracking Properties> 051 SheetMetalArea value=<Design Tracking Properties> 053 Appearance value=Copper - Satin<Design Tracking Properties> 054 Flat Pattern Defer Update value=vt=11<Inventor User Defined Properties> 001 TC_THICK value=<Inventor User Defined Properties> 002 TC_Testing Pressure value=vt=5<Inventor User Defined Properties> 003 TC_TO_APPROVER value=<Inventor User Defined Properties> 004 TC_CHANGE_NUMBER value=<Inventor User Defined Properties> 005 TC_CHANGE_REASON value=
318 Autodesk Inventor Programming in C++ by Owen Ransen
(C) 2021 Owen F Ransen
<Inventor User Defined Properties> 006 TC_CUST_MAT_CODE value=<Inventor User Defined Properties> 007 TC_DATE_CREAT value=19/12/2017<Inventor User Defined Properties> 008 TC_DATE_DRAWN value=23/05/2018<Inventor User Defined Properties> 009 TC_CUST_DWG_NO value=<Inventor User Defined Properties> 010 TC_CUSTOMERS value=<Inventor User Defined Properties> 011 TC_NOTE value=<Inventor User Defined Properties> 012 TC_ORDNO value=<Inventor User Defined Properties> 013 TC_MATERIAL value=<Inventor User Defined Properties> 014 TC_UOM value=<Inventor User Defined Properties> 015 TC_TO_APPROVAL_DATE value=
12.212.3iProperties, add a custom value programatically
If you want to add an iProperty into the visible custom properties...
320 Autodesk Inventor Programming in C++ by Owen Ransen
(C) 2021 Owen F Ransen
...use this function:
void AddCustomProperty(CComPtr<Document>& pInventorDoc, const CString& kcsPropName, const CString& kcsPropValue){ CComPtr <PropertySets> pPropSets; pInventorDoc->get_PropertySets(&pPropSets);
CComVariant varPropSetName(L"Inventor User Defined Properties"); CComPtr<PropertySet> pPropSet; HRESULT hRes = pPropSets->get_Item(varPropSetName,&pPropSet); if (FAILED(hRes) || (pPropSet == nullptr)) { ShowCOMError(hRes, L"Could not find custom property set"); return; }
CComPtr<Property> pProperty; CComVariant varPropName(kcsPropName) ; CComVariant varPropVal(kcsPropValue); CComVariant varPropId; pPropSet->Add(varPropVal, varPropName, varPropId, &pProperty);}
Here is an example of use:
CComQIPtr<Document> pDoc = pAssemblyDoc ; // upcast to Document AddCustomProperty(pDoc,gkcsInOutPropName,csInOut);
12.212.4iProperties, create a new property set
This function will create a new property set and optionally add in thefirst value of that property set:
void AddPropertySet(CComPtr<Document>& pInventorDoc, const CString& kcsNewPropSetName, const wchar_t* const pszFirstPropName /*= nullptr*/, const wchar_t* const pszFirstPropValue /*= nullptr*/){ CComPtr <PropertySets> pPropSets; pInventorDoc->get_PropertySets(&pPropSets);
CComPtr<PropertySet> pNewPropSet; CComVariant varInternalName; pPropSets->Add(CComBSTR(kcsNewPropSetName), varInternalName, &pNewPropSet);
321Programming Inventor in C++
(C) 2021 Owen F Ransen
if ((pszFirstPropName != nullptr) && (pszFirstPropValue != nullptr)) { CComPtr<Property> pProperty; CComVariant varPropVal(pszFirstPropValue); CComVariant varPropName(pszFirstPropName) ; CComVariant varPropId; pNewPropSet->Add(varPropVal, varPropName, varPropId, &pProperty); }}
12.212.5iProperties, read the value of a custom property
Here you go:
// Custom properties which are visible in the iProperties Custom tab have tobe// placed inside the "Inventor User Defined Properties" property setCString GetCustomPropertyValue(CComPtr<Document>& pInventorDoc, const CString& kcsPropName){ CComPtr <PropertySets> pPropSets; pInventorDoc->get_PropertySets(&pPropSets);
CComVariant varPropSetName(L"Inventor User Defined Properties"); CComPtr<PropertySet> pPropSet; HRESULT hRes = pPropSets->get_Item(varPropSetName,&pPropSet); if (FAILED(hRes) || (pPropSet == nullptr)) { ShowCOMError(hRes, L"Could not find custom property set"); return CString (L""); }
CComPtr<Property> pProp; CComVariant varPropName(kcsPropName); hRes = pPropSet->get_Item(varPropName, &pProp); if (FAILED(hRes) || (pPropSet == nullptr)) { // A property of this name does not exist return CString (L""); }
CComVariant varPropValue; pProp->get_Value(&varPropValue);
CString csValue; // If the variant is not a string this will remain empty if (varPropValue.vt == VT_BSTR) { csValue = CString(CComBSTR(varPropValue.bstrVal)); }
return csValue;}
322 Autodesk Inventor Programming in C++ by Owen Ransen
(C) 2021 Owen F Ransen
Here is an example of a call to the function:
// Upcast from a PartDocument to a general Document CComPtr<Document> pDoc; pDoc = pTuboDoc; const CString kcsMatName = GetCustomPropertyValue(pDoc,"OWEN_MAT");
13 Programming Inventor in C#
13.1 Starting Inventor in C#
The first thing to do is to make sure you can access Inventor usingC#. You have to ad a reference to the Inventor API like so:
323Programming Inventor in C#
(C) 2021 Owen F Ransen
Note that you need to choose the .NET Framework, elseGetActiveObject will not be found in Marshal:
In VS2019 the sequence is this:
324 Autodesk Inventor Programming in C++ by Owen Ransen
(C) 2021 Owen F Ransen
Then you can use the following code to get you going...
// CInventor starts up and closes down Inventor// 2019-07-02 : Started.
using System;using System.Collections.Generic;using System.Linq;using System.Text;using System.Threading.Tasks;using System.Runtime.InteropServices;using System.Windows.Forms;using System.Diagnostics;
namespace SAClassif{ static class CInventor { private static Inventor.Application m_Inventor; private static bool m_bWasAlreadyRunning = false;
public static bool ConnectToInventor () { Debug.WriteLine("Connecting to inventor..."); try { // See if Inventor is already running...
325Programming Inventor in C#
(C) 2021 Owen F Ransen
m_Inventor = (Inventor.Application)Marshal.GetActiveObject("Inventor.Application"); m_bWasAlreadyRunning = true; Debug.WriteLine("Inventor already running..."); } catch (Exception ex1) { Debug.WriteLine("Not running, will start it..."); m_bWasAlreadyRunning = false; try { Type invAppType = Type.GetTypeFromProgID("Inventor.Application"); m_Inventor = (Inventor.Application)System.Activator.CreateInstance(invAppType); m_Inventor.Visible = true; Debug.WriteLine("Started Inventor"); } catch (Exception ex2) { MessageBox.Show(ex2.ToString()); MessageBox.Show("Unable to start Inventor"); return false; } }
return m_Inventor != null; }
public static void DisconnectFromInventor() { if (m_Inventor == null) { return; }
if (m_bWasAlreadyRunning) { // I did not start Inventro so I shoulkd not close it... return; }
// Inventor was not running, you started it so you should shut itdown m_Inventor.Quit(); m_Inventor = null; } }}
326 Autodesk Inventor Programming in C++ by Owen Ransen
(C) 2021 Owen F Ransen
13.2 MSB3277: Found conflicts between different versions
You may get this sort of error if you change compiler. What youshould do is remove the reference from the project:
Then add a reference, browsing to the file Autodesk.Inventor.Interop.dll.
327Programming Inventor in C#
(C) 2021 Owen F Ransen
The whole horrible message is this:
warning MSB3277: Found conflicts between different versions of "Autodesk.Inventor.Interop" that could not be resolved.warning MSB3277: There was a conflict between "Autodesk.Inventor.Interop, Version=23.0.0.0, Culture=neutral, PublicKeyToken=d84147f8b4276564" and "Autodesk.Inventor.Interop, Version=23.2.0.0, Culture=neutral, PublicKeyToken=d84147f8b4276564".warning MSB3277: "Autodesk.Inventor.Interop, Version=23.0.0.0, Culture=neutral, PublicKeyToken=d84147f8b4276564" was chosen because it was primary and "Autodesk.Inventor.Interop, Version=23.2.0.0, Culture=neutral, PublicKeyToken=d84147f8b4276564" was not.warning MSB3277: References which depend on "Autodesk.Inventor.Interop, Version=23.0.0.0, Culture=neutral, PublicKeyToken=d84147f8b4276564" [C:\Program Files\Autodesk\Inventor 2019\Bin\Public Assemblies\Autodesk.Inventor.Interop.dll].warning MSB3277: C:\Program Files\Autodesk\Inventor 2019\Bin\Public Assemblies\Autodesk.Inventor.Interop.dllwarning MSB3277: Project file item includes which caused reference "C:\Program Files\Autodesk\Inventor 2019\Bin\Public Assemblies\Autodesk.Inventor.Interop.dll".warning MSB3277: Autodesk.Inventor.Interop, Version=23.0.0.0, Culture=neutral, PublicKeyToken=d84147f8b4276564, processorArchitecture=MSILwarning MSB3277: References which depend on "Autodesk.Inventor.Interop, Version=23.2.0.0, Culture=neutral, PublicKeyToken=d84147f8b4276564" [C:\WINDOWS\Microsoft.Net\assembly\GAC_MSIL\Autodesk.Inventor.Interop\v4.0_23.2.0.0__d84147f8b4276564\Autodesk.Inventor.Interop.dll].warning MSB3277: C:\Program Files\Autodesk\Inventor 2019\Bin\Autodesk.iLogic.Automation.dllwarning MSB3277: Project file item includes which caused reference "C:\Program Files\Autodesk\Inventor 2019\Bin\Autodesk.iLogic.Automation.dll".warning MSB3277: Autodesk.iLogic.Automationwarning MSB3277: C:\Program Files\Autodesk\Inventor 2019\Bin\Autodesk.iLogic.Interfaces.dllwarning MSB3277: Project file item includes which caused reference "C:\Program Files\Autodesk\Inventor 2019\Bin\Autodesk.iLogic.Interfaces.dll".warning MSB3277: Autodesk.iLogic.Automationwarning MSB3277: C:\Program Files\Autodesk\Inventor 2019\Bin\Autodesk.iLogic.Types.dllwarning MSB3277: Project file item includes which caused reference "C:\Program Files\Autodesk\Inventor 2019\Bin\Autodesk.iLogic.Types.dll".warning MSB3277: Autodesk.iLogic.Automation
328 Autodesk Inventor Programming in C++ by Owen Ransen
(C) 2021 Owen F Ransen
13.3 C# plugin making
Quick notes.
Install the SDK and this should appear in the new projects selection:
So far I've only got it to work in VS2017.
And you may not have all the Windows references, so you may haveto add them by hand...
329Programming Inventor in C#
(C) 2021 Owen F Ransen
...alternatively add a form and the IDE should bring in the requiredreferences.
You will get some sources which look like this:
using System;using System.Runtime.InteropServices;using System.Windows.Forms;using Inventor;using Microsoft.Win32;
namespace InventorAddIn1{ /// <summary> /// This is the primary AddIn Server class thatimplements the ApplicationAddInServer interface /// that all Inventor AddIns are required toimplement. The communication between Inventor and /// the AddIn is via the methods on this interface. /// </summary> [GuidAttribute("bc7a9e92-f455-431d-9378-c791092de1cc")]
330 Autodesk Inventor Programming in C++ by Owen Ransen
(C) 2021 Owen F Ransen
public class StandardAddInServer :Inventor.ApplicationAddInServer {
// Inventor application object. private Inventor.Applicationm_inventorApplication;
public StandardAddInServer() { }
#region ApplicationAddInServer Members
public voidActivate(Inventor.ApplicationAddInSite addInSiteObject, bool firstTime) { // This method is called by Inventor when itloads the addin. // The AddInSiteObject provides access tothe Inventor Application object. // The FirstTime flag indicates if the addinis loaded for the first time.
// Initialize AddIn members. m_inventorApplication =addInSiteObject.Application;
// TODO: Add ApplicationAddInServer.Activateimplementation. MessageBox.Show ("Hello"); }
public void Deactivate() { // This method is called by Inventor whenthe AddIn is unloaded.
331Programming Inventor in C#
(C) 2021 Owen F Ransen
// The AddIn will be unloaded eithermanually by the user or // when the Inventor session is terminated
// TODO: AddApplicationAddInServer.Deactivate implementation
// Release objects. m_inventorApplication = null;
GC.Collect(); GC.WaitForPendingFinalizers(); }
public void ExecuteCommand(int commandID) { // Note:this method is now obsolete, youshould use the // ControlDefinition functionality forimplementing commands. }
public object Automation { // This property is provided to allow theAddIn to expose an API // of its own to other programs. Typically,this would be done by // implementing the AddIn's API interface ina class and returning // that class object through this property.
get { // TODO: AddApplicationAddInServer.Automation getter implementation return null; }
332 Autodesk Inventor Programming in C++ by Owen Ransen
(C) 2021 Owen F Ransen
}
#endregion
}}
.
.
13.4 C# plugins, adding a button and a command
I've found that I can use the VS 2017 Inventor Plugin Maker wizardand then simply move all the sources over to VS 2019. I haven'tfound a VS2019 compatible wizard.
Many thanks to Jelte de Jong for getting me going on this subject.
I add the "Sample" panel to the "Tools" tab of the "Assembly" ribbon:
Here is the full code of a C# program which adds in a command,copiously commented.
// Adding a button and a command into an Inventor ribbon// 2021-10-18 : Started
333Programming Inventor in C#
(C) 2021 Owen F Ransen
using System;using System.Drawing;using System.Runtime.InteropServices;using System.Windows.Forms;using Inventor;using Microsoft.Win32;
namespace InventorAddIn1{ /// <summary> /// This is the primary AddIn Server class thatimplements the ApplicationAddInServer interface /// that all Inventor AddIns are required toimplement. The communication between Inventor and /// the AddIn is via the methods on this interface. /// </summary> [GuidAttribute("bc7a9e92-f455-431d-9378-c791092de1cc")] public class StandardAddInServer :Inventor.ApplicationAddInServer {
// Inventor application object... private Inventor.Applicationm_inventorApplication;
// The button I will add in... private ButtonDefinition m_sampleButton = null;
public StandardAddInServer() { }
// Inventor will call this if it finds a (this)DLL in the appropriate place, for example //C:\Users\ofr\AppData\Roaming\Autodesk\ApplicationPlugins\InventorAddIn1\InventorAddIn1.dll
334 Autodesk Inventor Programming in C++ by Owen Ransen
(C) 2021 Owen F Ransen
// We are passed Inventor application which memust hold and cherish... public voidActivate(Inventor.ApplicationAddInSite addInSiteObject, bool firstTime) {
// This method is called by Inventor when itloads the addin. // The AddInSiteObject provides access tothe Inventor Application object. // The FirstTime flag indicates if the addinis loaded for the first time. m_inventorApplication =addInSiteObject.Application;
// I use try-catch because Inventor swallowsthe exceptions silently and does not // warn you or the user that anything hasgone wrong. The catch will give you a clue // if something does go wrong... try { // This was me checking thatm_inventorApplication is initialized properly MessageBox.Show("locale=" +m_inventorApplication.Locale.ToString()) ; var cmdMgr =m_inventorApplication.CommandManager;
// Create the button (without icons,icons appear to be tricky)... m_sampleButton =cmdMgr.ControlDefinitions.AddButtonDefinition("Command1", // Display name "Command 1", // Internal name
335Programming Inventor in C#
(C) 2021 Owen F Ransen
CommandTypesEnum.kQueryOnlyCmdType, // No changes, justlooking Guid.NewGuid().ToString(), //Invent an id for this command "Command 1 description", "Command 1 Tooltip"); // showswhen mouse hovers
m_sampleButton.OnExecute +=ButtonDef_OnExecute; // Tell the button what it shoulddo when clicked, see function below
#if false // If you want show the name of eachribbon.... foreach (Ribbon r inm_inventorApplication.UserInterfaceManager.Ribbons) { MessageBox.Show(r.InternalName); }#endif
// Which of these Ribbons (lines) youchoose depends on whether you plug in handles Parts orAssemblies... // Ribbon TheRibbon =m_inventorApplication.UserInterfaceManager.Ribbons["Part"]; // command active when a part doc is active is open Ribbon TheRibbon =m_inventorApplication.UserInterfaceManager.Ribbons["Assembly"]; // command active when an assembly doc isactive
#if false
336 Autodesk Inventor Programming in C++ by Owen Ransen
(C) 2021 Owen F Ransen
// If you want show the name of each tabin the ribbon.... foreach (RibbonTab t inpartRibbon.RibbonTabs) { MessageBox.Show(t.InternalName); }#endif
RibbonTab toolsTab =TheRibbon.RibbonTabs["id_TabTools"]; // tools is presentin both parts and assemblies // MessageBox.Show ("tools tab internalname = " + toolsTab.InternalName); RibbonPanel customPanel =toolsTab.RibbonPanels.Add("Sample", "MysSample",Guid.NewGuid().ToString()); // MessageBox.Show("Custom panelinternal name = " + customPanel.InternalName);
customPanel.CommandControls.AddButton(m_sampleButton); } catch (Exception Err) { MessageBox.Show("Error " + Err.Message); }
MessageBox.Show ("Plugin loaded"); }
// This is the function you added to the buttona few lines above private void ButtonDef_OnExecute(NameValueMapContext) { // This is a test of calling a standard
337Programming Inventor in C#
(C) 2021 Owen F Ransen
Inventor command... m_inventorApplication.CommandManager.ControlDefinitions["AppZoomallCmd"].Execute();
// This is my simple test of something Ido... MessageBox.Show("My Command Called"); }
public void Deactivate() { // This method is called by Inventor whenthe AddIn is unloaded. // The AddIn will be unloaded eithermanually by the user or // when the Inventor session is terminated
// TODO: AddApplicationAddInServer.Deactivate implementation
// Release objects. m_inventorApplication = null;
GC.Collect(); GC.WaitForPendingFinalizers(); }
public void ExecuteCommand(int commandID) { // Note:this method is now obsolete, youshould use the // ControlDefinition functionality forimplementing commands. }
public object Automation {
338 Autodesk Inventor Programming in C++ by Owen Ransen
(C) 2021 Owen F Ransen
// This property is provided to allow theAddIn to expose an API // of its own to other programs. Typically,this would be done by // implementing the AddIn's API interface ina class and returning // that class object through this property.
get { // TODO: AddApplicationAddInServer.Automation getter implementation return null; } } }}
13.5 Button Definition
See this page also, it has a full implementation.
A button definition has two functions:
1. It is a definition of the aspect, look of the button2. It has an OnExecute member which lets you react to a user clicking
on the button
Note that a button definition is not a button, that will be explainedlater.
Icons of a button are optional, and can be of two sizes Normal sizeicons are 16 pixels wide by 16 pixels high. Large icons are 32 pixelswide by 32 pixels high. If an icon of a different size is provided,Inventor will scale it to fit.
A good place to actually add an instance of a button is in the Activate
339Programming Inventor in C#
(C) 2021 Owen F Ransen
member of your addin. Read and understand the comments here:
public void Activate(Inventor.ApplicationAddInSiteaddInSiteObject, bool firstTime) { // This method is called by Inventor when it loadsthe addin. // The AddInSiteObject provides access to theInventor Application object. // The FirstTime flag indicates if the addin isloaded for the first time.
// Initialize AddIn members. m_inventorApplication = addInSiteObject.Application;
// Control definitions are definitons of things likebuttons and menus... ControlDefinitions controlDefs =m_inventorApplication.CommandManager.ControlDefinitions;
// Create a *definition* of a button, what it lookslike mainly... m_buttonDefinition = controlDefs.AddButtonDefinition("Owen's Button", "invrSampleCommand", Inventor.CommandTypesEnum.kShapeEditCmdType, "{786675cb-d781-4f02-bfaa-02c4fda0ba61}", "Owens Desc", "Owens Tooltip") ; m_buttonDefinition.Enabled = true;
// Now we have to *place* the button somewhere. // This is a lot of drilling down...
// Get the object which handles the user interface... UserInterfaceManager userInterfaceManager; userInterfaceManager =m_inventorApplication.UserInterfaceManager; // Get the list of ribbons... Inventor.Ribbons ribbons;
340 Autodesk Inventor Programming in C++ by Owen Ransen
(C) 2021 Owen F Ransen
ribbons = userInterfaceManager.Ribbons;
// Get the "Part" ribbon, a list of tabs active whenediting a part... Inventor.Ribbon partRibbon; partRibbon = ribbons["Part"];
// Get the tabs associated with part ribbon RibbonTabs ribbonTabs; ribbonTabs = partRibbon.RibbonTabs;
// In particular get the "tools" tab... RibbonTab partSketchRibbonTab; partSketchRibbonTab = ribbonTabs["id_TabTools"]; // Inside the "Tools" tab there are many panels... RibbonPanels ribbonPanels; ribbonPanels = partSketchRibbonTab.RibbonPanels;
// Get the measurepent panel... RibbonPanel ribbonPanel; ribbonPanel = ribbonPanels["id_PanelP_ToolsMeasure"];
// Finally we can add the button... ribbonPanel.CommandControls.AddButton(m_buttonDefinition); }
The Gui heirachy is illustrated here:
341Programming Inventor in C#
(C) 2021 Owen F Ransen
13.6 C# plugin removal
To remove an add in it looks like you need to remove the subdirectory which contains it, for example:
C:\Users\ofr\AppData\Roaming\Autodesk\ApplicationPlugins\InventorAddIn1
It'll look something like this:
342 Autodesk Inventor Programming in C++ by Owen Ransen
(C) 2021 Owen F Ransen
13.7 C# message box
You can either use the standard windows one:
public voidActivate(Inventor.ApplicationAddInSite addInSiteObject, bool firstTime) { // This method is called by Inventor when itloads the addin. // The AddInSiteObject provides access tothe Inventor Application object. // The FirstTime flag indicates if the addinis loaded for the first time.
// Initialize AddIn members. m_inventorApplication =addInSiteObject.Application;
// TODO: Add ApplicationAddInServer.Activateimplementation. MessageBox.Show ("Hello"); }
or the Inventor one:
You can use build-in "message box" inventorApp.CommandManager.PromptMessage(...), but its usage is little bit obscure. See APIreference for more information.
343Programming Inventor in C#
(C) 2021 Owen F Ransen
Advantage of this is when Inventor is in silent mode, thisPromptMessage is not displayed and don't block application.
When you use MessageBox, this is displayed always and user MUSTclose them. This may be a trouble when you run some automatic taskwithout user interaction.
Enter topic text here.
13.8 Custom iProperties using C#
Here's a function to get the iProperties of an assembly:
static PropertySet GetCustomiProperties (Inventor.AssemblyDocumentInvIAMDoc) { if (InvIAMDoc == null) { return null; }
// We will find the things to send to the classifier inside thecustom iPropertyies PropertySets Sets = InvIAMDoc.PropertySets;
PropertySet CustomSet = null;
// Look in all the property sets for custom user properties... foreach (PropertySet s in Sets) { if (s.Name == "Inventor User Defined Properties") { CustomSet = s; break; } }
return CustomSet; }
344 Autodesk Inventor Programming in C++ by Owen Ransen
(C) 2021 Owen F Ransen
13.9 Open an Inventor file using C#
You can use Open or OpenWithOptions. Here's how to do it withOpenWithOptions:
NameValueMap Options = m_Inventor.TransientObjects.CreateNameValueMap () ; // Some example options.... Options.Add("SkipAllUnresolvedFiles", true); Options.Add("DesignViewRepresentation", "View1"); Options.Add("DeferUpdates", true);
AssemblyDocument IamDoc = (AssemblyDocument)m_Inventor.Documents.OpenWithOptions(sFullDocName,Options,true);
The last true means Open Visible.
The DeferUpdates in interesting. If you turn defer updates on,Inventor blocks all kinds of editability, to the in-memory data. But thefile itself stays as is, so that is what I use for read-only processing,where I only want to read from the file, and not modify it.
13.10 ItemByName for Document
The syntax is as follows:
Document Doc = (Document)m_Inventor.Documents.ItemByName(sFullDocName) ;
You need that cast to (Document).
13.11 Get user parameters using C#
Here's how to do it:
// Returns the string value of the user parameter namedin the input static string GetUserParam (Inventor.AssemblyDocument
345Programming Inventor in C#
(C) 2021 Owen F Ransen
InvIAMDoc, string sUserParamName) { UserParameters UsrParams =InvIAMDoc.ComponentDefinition.Parameters.UserParameters;
int iNumUsrParms = UsrParams.Count;
for (int mp = 1; mp <= iNumUsrParms; mp++) { // Get this user parameter UserParameter UsrParam = UsrParams[mp];
// Compare its name to what we are looking for bool bIsMyParam = (string.Compare(UsrParam.Name,sUserParamName, StringComparison.OrdinalIgnoreCase) == 0);
// Return the value if it is the one... if (bIsMyParam) { string sMsg = string.Format("Found {0} withvalue {1} ", UsrParam.Name.ToString(),UsrParam.Value.ToString()); Debug.WriteLine(sMsg); return UsrParam.Value; } }
return ""; }
13.12 Looping over components inside an assembly in C#
Here's an example of how to do it, assuming you already have anASM doc:
AssemblyComponentDefinition Definition =InvIAMDoc.ComponentDefinition; ComponentOccurrences Occurences = Definition.Occurrences;
Debug.WriteLine ("There are " + Occurences.Count.ToString() + "occurrences") ;
346 Autodesk Inventor Programming in C++ by Owen Ransen
(C) 2021 Owen F Ransen
foreach (ComponentOccurrence ThisOcc in Occurences) { ComponentDefinition ThisDef = ThisOcc.Definition; Debug.WriteLine("Found something "); if (ThisDef.Type == ObjectTypeEnum.kAssemblyComponentDefinitionObject) { AssemblyComponentDefinition AsmDef = (AssemblyComponentDefinition)ThisDef; Material Mat = AsmDef.DefaultMaterial; AssemblyDocument AsmDoc = AsmDef.Document; Debug.WriteLine("Found an assembly of " + Mat.Name + " " +AsmDoc.FullDocumentName); } if (ThisDef.Type == ObjectTypeEnum.kPartComponentDefinitionObject) { PartComponentDefinition PartDef = (PartComponentDefinition)ThisDef; PartDocument PartDoc = PartDef.Document; Debug.WriteLine("Found an part " + PartDef.Material.Name+ " " + PartDoc.FullDocumentName) ; } }
347Programming Inventor in C#
(C) 2021 Owen F Ransen
13.13 GetActiveObject does not exist in Marshal
This may happen to you if you have not used the correct framework.
Other project types may not have the correct Marshall function.
13.14 Calling iLogic from C#
Remember to have Autodesk.iLogic.Automation.dll as a reference...
348 Autodesk Inventor Programming in C++ by Owen Ransen
(C) 2021 Owen F Ransen
Here is an example, the dynamic keyword is important apparently:
using System;using System.Windows.Forms;using Inventor;
namespace OInventor{ public partial class Form1 : Form { static Inventor.Application m_Inventor; // static Inventor.ApplicationAddIn m_AddIn;
public Form1() { InitializeComponent(); }
private void Form1_Load(object sender, EventArgs e) { m_Inventor = (Inventor.Application)System.Runtime.InteropServices.Marshal.GetActiveObject("Inventor.Application");
int iNumDocs = m_Inventor.Documents.Count; MessageBox.Show("There are " + iNumDocs.ToString() + " documents");
string iLogicAddinGuid = "{3BDD8D79-2179-4B11-8A5A-257B1C0263AC}";
Inventor.ApplicationAddIn addin = null;
try { // try to get iLogic addin addin = m_Inventor.ApplicationAddIns.get_ItemById(iLogicAddinGuid); } catch {
349Programming Inventor in C#
(C) 2021 Owen F Ransen
return; }
if (addin != null) { // activate the addin if (!addin.Activated) addin.Activate();
dynamic _iLogicAutomation1 = addin.Automation;
Document oCurrentDoc1 = m_Inventor.ActiveDocument;
_iLogicAutomation1.RunRule(oCurrentDoc1, "Pippo"); } } }}
Note that you have to have included the Autodesk.iLogic.Automationreference in your product references:
351Programming Inventor in C#
(C) 2021 Owen F Ransen
13.15 Listing iLogic rules using C#
Remember to have Autodesk.iLogic.Automation.dll as a reference...
This works:
string iLogicAddinGuid ="{3BDD8D79-2179-4B11-8A5A-257B1C0263AC}"; Inventor.ApplicationAddIn addin = null; try { addin =m_Inventor.ApplicationAddIns.get_ItemById(iLogicAddinGuid); } catch { MessageBox.Show("Could not get iLogicobject"); }
if (addin != null) { if (!addin.Activated) {
352 Autodesk Inventor Programming in C++ by Owen Ransen
(C) 2021 Owen F Ransen
addin.Activate(); }
dynamic _iLogicAutomation =addin.Automation; _iLogicAutomation.CallingFromOutside = true;
dynamic AllRules =_iLogicAutomation.Rules(m_Inventor.ActiveDocument);
if (AllRules == null) { MessageBox.Show("There are no rulesin this document"); return; }
foreach (/*iLogicRule*/ dynamicThisRule in AllRules) { MessageBox.Show("name of rule = " +ThisRule.Name); } }
It was modified from code found here:
https://forums.autodesk.com/t5/inventor-customization/call-ilogic-from-net-c-inventor-2018/m-p/8522694/highlight/true#M93226
13.16 Save programatically in C#
Save is a bit odd. It will throw an exception if the user chooses not tooverwrite an existing file. Here's my solution:
353Programming Inventor in C#
(C) 2021 Owen F Ransen
string sFullFileName = CInvSettings.sPlmCacheDir +m_Spec.sBatCode + ".IAM";if (System.IO.File.Exists (sFullFileName)){ // I need to delete the file if it already exists elseAsmDoc.Save will throw an exception // if the user says no to ovewrite. DialogResult Res = MessageBox.Show(m_Spec.sBatCode + "esiste, sovrascrivere?", "Sovrascrivere?",MessageBoxButtons.YesNo); if (Res == DialogResult.Yes) { // Stop Save() from thowing an exception System.IO.File.Delete(sFullFileName); } else { Cursor.Current = Cursors.Default; return; }}
AsmDoc.FullFileName = sFullFileName;AsmDoc.Save();
13.17 "Member not found" error in C# add-in
As mentioned in other blog posts (e.g. here and here) as well, usingEmbed Interop Types = True with the Inventor interop assembly doesnot work well.
Apart from some events not firing, you might not find all the propertieseither. E.g. in the case of a Parameter object, when doing this:
var unitType = param.get_Units();
I get this error:
{"Member not found. (Exception from HRESULT: 0x80020003(DISP_E_MEMBERNOTFOUND))"}
So just set Embed Interop Types to False:
354 Autodesk Inventor Programming in C++ by Owen Ransen
(C) 2021 Owen F Ransen
EmbedInteoropTypes
Just for completeness' sake (though the above solution should solvethe problem), there could be another way as well to avoid this error.You could declare a dynamic variable for the parameter (in order touse late-binding) and access the property through that:
dynamic p = param;var unitType = p.Units;
- Adam
355Programming Inventor in C#
(C) 2021 Owen F Ransen
13.18 Browser panes in C#
Aech document has its own browser panes (panels):
Inventor.BrowserPanes Panes =m_Inventor.ActiveDocument.BrowserPanes;
foreach (Inventor.BrowserPane ThisPane in Panes) { MessageBox.Show("Pane internal name: <" +ThisPane.InternalName + "> = <" + ThisPane.Name + ">"); }
MessageBox.Show(m_Inventor.LanguageName + " " +m_Inventor.LanguageCode.ToString());
13.19 Assembly document or part document?
You can try casting with the As keyword to find out what sort ofdocument you have:
Inventor.AssemblyDocument AsmDoc = m_Inventor.ActiveDocument as Inventor.AssemblyDocument;if (AsmDoc != null){
MessageBox.Show("This is an assembly");}else {
Inventor.PartDocument PartDoc = m_Inventor.ActiveDocument as Inventor.PartDocument;if (PartDoc != null){
MessageBox.Show("This is a part");}else {
MessageBox.Show("This is something else");}
}
356 Autodesk Inventor Programming in C++ by Owen Ransen
(C) 2021 Owen F Ransen
13.20 Listing parameters in an assembly, C#
Here is the code, note the foreach loop.
private void ListParameters_Click(object sender,EventArgs e) { Inventor.AssemblyDocument AsmDoc =m_Inventor.ActiveDocument as Inventor.AssemblyDocument; if (AsmDoc == null) { MessageBox.Show("This is not an assembly"); return; }
UserParameters UsrParams =AsmDoc.ComponentDefinition.Parameters.UserParameters; foreach (UserParameter UserParam in UsrParams) { string sMsg = string.Format("Found {0} with value{1} ", UserParam.Name.ToString(), UserParam.Value.ToString()); MessageBox.Show(sMsg); } }
The above works for user parameters, here is the loop for modelparameters:
ModelParameters ModParams =AsmDoc.ComponentDefinition.Parameters.ModelParameters; foreach (ModelParameter ModParam in ModParams) { string sMsg = string.Format("Found model param{0} with value {1} ", ModParam.Name.ToString(),ModParam.Value.ToString()); MessageBox.Show(sMsg); }
357Programming Inventor in C#
(C) 2021 Owen F Ransen
13.21 Getting the value of a parameter in a part
Here you go:
public static double GetPartMmParam (PartComponentDefinition PartDef, ParamType_e eParamType, string sParamName) { if (PartDef == null) { AutoBatSupp.Log.WriteLn(CLog.Type_e.ekErr,"SetAsmParam null AsmDef (" + sParamName + ")" + eParamType.ToString()); return 0.0 ; } if (!PartCompDefHasParam(PartDef, eParamType, sParamName)) { AutoBatSupp.Log.WriteLn(CLog.Type_e.ekErr,"Assembly does not have parameter <" + sParamName + ">, " + eParamType.ToString()); return 0.0; }
// This will become a User or Model Parameter Parameter Param = null;
if (eParamType == ParamType_e.ekModel) { ModelParameters ModelParams = PartDef.Parameters.ModelParameters; ModelParameter ThisParam = ModelParams[sParamName]; Param = (Parameter)ThisParam; } else if (eParamType == ParamType_e.ekUser) { UserParameters ModelParams = PartDef.Parameters.UserParameters; UserParameter ThisParam = ModelParams[sParamName]; Param = (Parameter)ThisParam; }
return (double)Param.Value * 10.0; }
13.22 Value of a Param
Though it is odd you may have to cast a Parameter Param.Value toget hold of its double value. look at the last line of this:
if (eParamType == ParamType_e.ekModel) {
358 Autodesk Inventor Programming in C++ by Owen Ransen
(C) 2021 Owen F Ransen
ModelParameters ModelParams = PartDef.Parameters.ModelParameters; ModelParameter ThisParam = ModelParams[sParamName]; Param = (Parameter)ThisParam; } else if (eParamType == ParamType_e.ekUser) { UserParameters ModelParams = PartDef.Parameters.UserParameters; UserParameter ThisParam = ModelParams[sParamName]; Param = (Parameter)ThisParam; }
return (double)Param.Value * 10.0;
13.23 Getting the GUI language of Inventor
This works:
MessageBox.Show(m_Inventor.LanguageName + " " + m_Inventor.LanguageCode.ToString());
Here is an example of LanguageName: "English" andLanguageCode: "en-US"
13.24 Changing parameters with C#
Here is an example of changing model parameters of a part:
private void ChangeCyl_Click(object sender,EventArgs e) { Inventor.PartDocument PartDoc =m_Inventor.ActiveDocument as Inventor.PartDocument; if (PartDoc == null) { MessageBox.Show("This is not a part"); return; }
359Programming Inventor in C#
(C) 2021 Owen F Ransen
ModelParameters ModParams =PartDoc.ComponentDefinition.Parameters.ModelParameters; foreach (ModelParameter ModParam inModParams) { if (ModParam.Name == "Diametro") { ModParam.Value = 111.0; // .Value isin cm .Expression would be in mm } else if (ModParam.Name == "Altezza") { ModParam.Value = 55.0; // .Value isin cm .Expression would be in mm } }
PartDoc.Update(); }
Note also the comment about .Value and .Expression, as well as thecall to update the part. See also get_Units.
I have this set of functions for changing parameters:
public enum ParamType_e { ekModel, ekUser, };
public static void SetAsmParam(Inventor.AssemblyComponentDefinition AsmDef, ParamType_e eParamType, string sParamName, doubleNewVal) { if (AsmDef == null) {
360 Autodesk Inventor Programming in C++ by Owen Ransen
(C) 2021 Owen F Ransen
MessageBox.Show("SetAsmParam null AsmDef (" +sParamName + ")" + eParamType.ToString ()); return; } if (!AsmCompDefHasParam(AsmDef,eParamType,sParamName)) { MessageBox.Show("Assembly does not have parameter<" + sParamName + ">, " + eParamType.ToString()); return; }
// This will become a User or Model Parameter Parameter Param = null;
if (eParamType == ParamType_e.ekModel) { ModelParameters ModelParams =AsmDef.Parameters.ModelParameters; ModelParameter ThisParam =ModelParams[sParamName]; if (ThisParam == null) { MessageBox.Show("Cannot find assembly modelparam: " + sParamName); return; } Param = (Parameter)ThisParam; } else if (eParamType == ParamType_e.ekUser) { UserParameters ModelParams =AsmDef.Parameters.UserParameters; UserParameter ThisParam =ModelParams[sParamName]; if (ThisParam == null) { MessageBox.Show("Cannot find assembly userparam: " + sParamName); return; } Param = (Parameter)ThisParam; }
if (Param != null)
361Programming Inventor in C#
(C) 2021 Owen F Ransen
{ Param.Value = NewVal; MessageBox.Show(Param.get_Units()); } }
public static voidSetAsmUlParam(Inventor.AssemblyComponentDefinition AsmDef, ParamType_e eParamType, string sParamName,double NewVal) { SetAsmParam(AsmDef, eParamType, sParamName, NewVal); }
public static voidSetAsmMmParam(Inventor.AssemblyComponentDefinition AsmDef, ParamType_e eParamType, string sParamName,double mmUserParamNewVal) { // Note the division by 10 because of cm native uintsin Inventor SI SetAsmParam(AsmDef, eParamType, sParamName,mmUserParamNewVal / 10.0); }
13.25 get_Units crashes
If you have a parameter then you may not be able to use get_Units(C# version of the VBA Units function). Your C# call to get_Units willcrash if you have not set Embed Interop _Types to true:
362 Autodesk Inventor Programming in C++ by Owen Ransen
(C) 2021 Owen F Ransen
The crash will look like this:
This can Enter topic text here.
363Programming Inventor in C#
(C) 2021 Owen F Ransen
13.26 Listing holes in a face of folded metal
Here is a face with a hole in it, actually a cut:
If you have that part open you can run this:
public static void Test () { PartDocument PartDoc; try { PartDoc = (PartDocument)m_Inventor.ActiveDocument asPartDocument; if (PartDoc == null) { MessageBox.Show("This is not a part document"); return; } } catch { MessageBox.Show ("not a part doc"); return; }
PartComponentDefinition PartDef = PartDoc.ComponentDefinition; PartFeatures FeatsList = PartDef.Features;
foreach (PartFeature ThisFeature in FeatsList) { if (ThisFeature.Type == ObjectTypeEnum.kCutFeatureObject) {
364 Autodesk Inventor Programming in C++ by Owen Ransen
(C) 2021 Owen F Ransen
CutFeature CutFeature = (CutFeature)ThisFeature; ProfilePath TheProfile = CutFeature.Definition.Profile[1]; ProfileEntity Ent = TheProfile[1];
Debug.WriteLine ("Profile ent " + Ent.ToString() + " " +Ent.CurveType.ToString());
if (Ent.CurveType == Curve2dTypeEnum.kCircleCurve2d) { Circle2d Circle = (Circle2d)Ent.Curve; Debug.WriteLine("It is a circle of radius " +Circle.Radius.ToString()); } } else if (ThisFeature.Type ==ObjectTypeEnum.kFaceFeatureObject) { FaceFeature FaceFeat = (FaceFeature)ThisFeature; MessageBox.Show("FaceFeature " + FaceFeat.ToString() + "name<" + FaceFeat.Name + "> has " + FaceFeat.Faces.Count.ToString() + " faces");
//Faces FacesList = FaceFeat.Faces; //FaceFeat.Definition.
//foreach (Face ThisFace in FacesList) //{ // Face.Edges;
//}
} else { MessageBox.Show("This feature is a " +ThisFeature.Type.ToString()); } } }
And you will get this output in the debug window of the IDE:
Profile ent System.__ComObject kCircleCurve2d
It is a circle of radius 0,15.
See also this.
365Programming Inventor in C#
(C) 2021 Owen F Ransen
13.27 Listing holes in a face of folded metal VB
This code was the starting point for this.
// Set a reference to the sheet metal document. // This assumes a part document is active. Dim oPartDoc As PartDocument Set oPartDoc = ThisApplication.ActiveDocument // Make sure the document is a sheet metal document. if (oPartDoc.SubType == "{9C464203-9BAE-11D3-8BAD-0060B0CE6BB4}")
{ MessageBox.Show ("A sheet metal document must be open.") return } // Get the sheet metal component definition. Because this is a partdocument whose // sub type is sheet metal, the document will return aSheetMetalComponentDefinition // instead of a PartComponentDefinition. Dim oSheetMetalCompDef As SheetMetalComponentDefinition Set oSheetMetalCompDef = oPartDoc.ComponentDefinition // Iterate through the features looking specifically for sheet metalfeatures. Dim oFeature As PartFeature For Each oFeature In oSheetMetalCompDef.Features switch (oFeature.Type) { Case kFaceFeatureObject Dim oFaceFeature As FaceFeature Set oFaceFeature = oFeature Debug.WriteLine ( "Face Feature: " + oFaceFeature.Name); Debug.WriteLine ( " Adaptive: " + oFaceFeature.Adaptive); Debug.WriteLine ( " Face Count: " + oFaceFeature.Faces.Count) ; Debug.WriteLine ( " HealthStatus: " + oFaceFeature.
366 Autodesk Inventor Programming in C++ by Owen Ransen
(C) 2021 Owen F Ransen
HealthStatus) ; Debug.WriteLine ( " RangeBox: (" + Format(oFaceFeature.RangeBox.MinPoint.X, "0.00000") + ", " + Format(oFaceFeature.RangeBox.MinPoint.Y, "0.00000") + ", " + Format(oFaceFeature.RangeBox.MinPoint.Z, "0.00000") + ")-(" + Format(oFaceFeature.RangeBox.MaxPoint.X, "0.00000") + ", " + Format(oFaceFeature.RangeBox.MaxPoint.Y, "0.00000") + ", " + Format(oFaceFeature.RangeBox.MaxPoint.Z, "0.00000") + ")" ) ; Debug.WriteLine ( " Suppressed: " + oFaceFeature.Suppressed ;
break ;
Case kContourFlangeFeatureObject Dim oContourFlangeFeature As ContourFlangeFeature Set oContourFlangeFeature = oFeature Debug.WriteLine ( "Contour Flange Feature: " +oContourFlangeFeature.Name) ; Debug.WriteLine ( " Adaptive: " + oContourFlangeFeature.Adaptive) ; Debug.WriteLine ( " Face Count: " +oContourFlangeFeature.Faces.Count) ; Debug.WriteLine ( " HealthStatus: " +oContourFlangeFeature.HealthStatus) ; Debug.WriteLine ( " RangeBox: (" + Format(oFaceFeature.RangeBox.MinPoint.X, "0.00000") + ", " + Format(oFaceFeature.RangeBox.MinPoint.Y, "0.00000") + ", " + Format(oFaceFeature.RangeBox.MinPoint.Z, "0.00000") + ")-(" + Format(oFaceFeature.RangeBox.MaxPoint.X, "0.00000") + ", " + Format(oFaceFeature.RangeBox.MaxPoint.Y, "0.00000") + ", " + Format(oFaceFeature.RangeBox.MaxPoint.Z, "0.00000") + ")") ;
367Programming Inventor in C#
(C) 2021 Owen F Ransen
Debug.WriteLine ( " Suppressed: " +oContourFlangeFeature.Suppressed ;
break ;
Case kCutFeatureObject Dim oCutFeature As CutFeature Set oCutFeature = oFeature Debug.WriteLine ( "Cut Feature: " + oCutFeature.Name) ; Debug.WriteLine ( " Adaptive: " + oCutFeature.Adaptive) ; Debug.WriteLine ( " Face Count: " + oCutFeature.Faces.Count) ; Debug.WriteLine ( " HealthStatus: " + oCutFeature.HealthStatus) ; Debug.WriteLine ( " RangeBox: (" + Format(oFaceFeature.RangeBox.MinPoint.X, "0.00000") + ", " + Format(oFaceFeature.RangeBox.MinPoint.Y, "0.00000") + ", " + Format(oFaceFeature.RangeBox.MinPoint.Z, "0.00000") + ")-(" + Format(oFaceFeature.RangeBox.MaxPoint.X, "0.00000") + ", " + Format(oFaceFeature.RangeBox.MaxPoint.Y, "0.00000") + ", " + Format(oFaceFeature.RangeBox.MaxPoint.Z, "0.00000") + ")") ; Debug.WriteLine ( " Suppressed: " + oCutFeature.Suppressed
break ;
Case kFlangeFeatureObject Dim oFlangeFeature As FlangeFeature Set oFlangeFeature = oFeature Debug.WriteLine ( "Flange Feature: " + oFlangeFeature.Name Debug.WriteLine ( " Adaptive: " + oFlangeFeature.Adaptive Debug.WriteLine ( " Face Count: " + oFlangeFeature.Faces.Count Debug.WriteLine ( " HealthStatus: " + oFlangeFeature.HealthStatus
368 Autodesk Inventor Programming in C++ by Owen Ransen
(C) 2021 Owen F Ransen
Debug.WriteLine ( " RangeBox: (" + Format(oFaceFeature.RangeBox.MinPoint.X, "0.00000") + ", " + Format(oFaceFeature.RangeBox.MinPoint.Y, "0.00000") + ", " + Format(oFaceFeature.RangeBox.MinPoint.Z, "0.00000") + ")-(" + Format(oFaceFeature.RangeBox.MaxPoint.X, "0.00000") + ", " + Format(oFaceFeature.RangeBox.MaxPoint.Y, "0.00000") + ", " + Format(oFaceFeature.RangeBox.MaxPoint.Z, "0.00000") + ")" Debug.WriteLine ( " Suppressed: " + oFlangeFeature.Suppressed
break ;
Case kHemFeatureObject Dim oHemFeature As HemFeature Set oHemFeature = oFeature Debug.WriteLine ( "Hem Feature: " + oHemFeature.Name Debug.WriteLine ( " Adaptive: " + oHemFeature.Adaptive Debug.WriteLine ( " Face Count: " + oHemFeature.Faces.Count Debug.WriteLine ( " HealthStatus: " + oHemFeature.HealthStatus Debug.WriteLine ( " RangeBox: (" + Format(oFaceFeature.RangeBox.MinPoint.X, "0.00000") + ", " + Format(oFaceFeature.RangeBox.MinPoint.Y, "0.00000") + ", " + Format(oFaceFeature.RangeBox.MinPoint.Z, "0.00000") + ")-(" + Format(oFaceFeature.RangeBox.MaxPoint.X, "0.00000") + ", " + Format(oFaceFeature.RangeBox.MaxPoint.Y, "0.00000") + ", " + Format(oFaceFeature.RangeBox.MaxPoint.Z, "0.00000") + ")" Debug.WriteLine ( " Suppressed: " + oHemFeature.Suppressed
break ;
369Programming Inventor in C#
(C) 2021 Owen F Ransen
Case kFoldFeatureObject Dim oFoldFeature As FoldFeature Set oFoldFeature = oFeature Debug.WriteLine ( "Fold Feature: " + oFoldFeature.Name Debug.WriteLine ( " Adaptive: " + oFoldFeature.Adaptive Debug.WriteLine ( " Face Count: " + oFoldFeature.Faces.Count Debug.WriteLine ( " HealthStatus: " + oFoldFeature.HealthStatus Debug.WriteLine ( " RangeBox: (" + Format(oFaceFeature.RangeBox.MinPoint.X, "0.00000") + ", " + Format(oFaceFeature.RangeBox.MinPoint.Y, "0.00000") + ", " + Format(oFaceFeature.RangeBox.MinPoint.Z, "0.00000") + ")-(" + Format(oFaceFeature.RangeBox.MaxPoint.X, "0.00000") + ", " + Format(oFaceFeature.RangeBox.MaxPoint.Y, "0.00000") + ", " + Format(oFaceFeature.RangeBox.MaxPoint.Z, "0.00000") + ")" Debug.WriteLine ( " Suppressed: " + oFoldFeature.Suppressed
break ;
Case kCornerFeatureObject Dim oCornerFeature As CornerFeature Set oCornerFeature = oFeature Debug.WriteLine ( "Corner Seam Feature: " +oCornerFeature.Name Debug.WriteLine ( " Adaptive: " + oCornerFeature.Adaptive Debug.WriteLine ( " Face Count: " + oCornerFeature.Faces.Count Debug.WriteLine ( " HealthStatus: " + oCornerFeature.HealthStatus Debug.WriteLine ( " RangeBox: (" + Format(oFaceFeature.RangeBox.MinPoint.X, "0.00000") + ", " + Format(oFaceFeature.RangeBox.MinPoint.
370 Autodesk Inventor Programming in C++ by Owen Ransen
(C) 2021 Owen F Ransen
Y, "0.00000") + ", " + Format(oFaceFeature.RangeBox.MinPoint.Z, "0.00000") + ")-(" + Format(oFaceFeature.RangeBox.MaxPoint.X, "0.00000") + ", " + Format(oFaceFeature.RangeBox.MaxPoint.Y, "0.00000") + ", " + Format(oFaceFeature.RangeBox.MaxPoint.Z, "0.00000") + ")" Debug.WriteLine ( " Suppressed: " + oCornerFeature.Suppressed
break ;
Case kBendFeatureObject Dim oBendFeature As BendFeature Set oBendFeature = oFeature Debug.WriteLine ( "Bend Feature: " + oBendFeature.Name Debug.WriteLine ( " Adaptive: " + oBendFeature.Adaptive Debug.WriteLine ( " Face Count: " + oBendFeature.Faces.Count Debug.WriteLine ( " HealthStatus: " + oBendFeature.HealthStatus Debug.WriteLine ( " RangeBox: (" + Format(oFaceFeature.RangeBox.MinPoint.X, "0.00000") + ", " + Format(oFaceFeature.RangeBox.MinPoint.Y, "0.00000") + ", " + Format(oFaceFeature.RangeBox.MinPoint.Z, "0.00000") + ")-(" + Format(oFaceFeature.RangeBox.MaxPoint.X, "0.00000") + ", " + Format(oFaceFeature.RangeBox.MaxPoint.Y, "0.00000") + ", " + Format(oFaceFeature.RangeBox.MaxPoint.Z, "0.00000") + ")" Debug.WriteLine ( " Suppressed: " + oBendFeature.Suppressed
break ;
Case kCornerRoundFeatureObject Dim oCornerRoundFeature As CornerRoundFeature
371Programming Inventor in C#
(C) 2021 Owen F Ransen
Set oCornerRoundFeature = oFeature Debug.WriteLine ( "Corner Round Feature: " +oCornerRoundFeature.Name Debug.WriteLine ( " Adaptive: " + oCornerRoundFeature.Adaptive Debug.WriteLine ( " Face Count: " +oCornerRoundFeature.Faces.Count Debug.WriteLine ( " HealthStatus: " +oCornerRoundFeature.HealthStatus Debug.WriteLine ( " RangeBox: (" + Format(oFaceFeature.RangeBox.MinPoint.X, "0.00000") + ", " + Format(oFaceFeature.RangeBox.MinPoint.Y, "0.00000") + ", " + Format(oFaceFeature.RangeBox.MinPoint.Z, "0.00000") + ")-(" + Format(oFaceFeature.RangeBox.MaxPoint.X, "0.00000") + ", " + Format(oFaceFeature.RangeBox.MaxPoint.Y, "0.00000") + ", " + Format(oFaceFeature.RangeBox.MaxPoint.Z, "0.00000") + ")" Debug.WriteLine ( " Suppressed: " +oCornerRoundFeature.Suppressed
break ;
Case kCornerChamferFeatureObject Dim oCornerChamferFeature As CornerChamferFeature Set oCornerChamferFeature = oFeature Debug.WriteLine ( "Corner Chamfer Feature: " +oCornerChamferFeature.Name Debug.WriteLine ( " Adaptive: " +oCornerChamferFeature.Adaptive Debug.WriteLine ( " Face Count: " +oCornerChamferFeature.Faces.Count Debug.WriteLine ( " HealthStatus: " +oCornerChamferFeature.HealthStatus Debug.WriteLine ( " RangeBox: (" + Format(oFaceFeature.RangeBox.MinPoint.X, "0.00000") + ", " + Format(oFaceFeature.RangeBox.MinPoint.Y, "0.00000") + ", " +
372 Autodesk Inventor Programming in C++ by Owen Ransen
(C) 2021 Owen F Ransen
Format(oFaceFeature.RangeBox.MinPoint.Z, "0.00000") + ")-(" + Format(oFaceFeature.RangeBox.MaxPoint.X, "0.00000") + ", " + Format(oFaceFeature.RangeBox.MaxPoint.Y, "0.00000") + ", " + Format(oFaceFeature.RangeBox.MaxPoint.Z, "0.00000") + ")" Debug.WriteLine ( " Suppressed: " +oCornerChamferFeature.Suppressed
break ;
Case kPunchToolFeatureObject Dim oPunchToolFeature As PunchToolFeature Set oPunchToolFeature = oFeature Debug.WriteLine ( "Punch Tool Feature: " +oPunchToolFeature.Name Debug.WriteLine ( " Adaptive: " + oPunchToolFeature.Adaptive Debug.WriteLine ( " Face Count: " + oPunchToolFeature.Faces.Count Debug.WriteLine ( " HealthStatus: " + oPunchToolFeature.HealthStatus Debug.WriteLine ( " RangeBox: (" + Format(oFaceFeature.RangeBox.MinPoint.X, "0.00000") + ", " + Format(oFaceFeature.RangeBox.MinPoint.Y, "0.00000") + ", " + Format(oFaceFeature.RangeBox.MinPoint.Z, "0.00000") + ")-(" + Format(oFaceFeature.RangeBox.MaxPoint.X, "0.00000") + ", " + Format(oFaceFeature.RangeBox.MaxPoint.Y, "0.00000") + ", " + Format(oFaceFeature.RangeBox.MaxPoint.Z, "0.00000") + ")" Debug.WriteLine ( " Suppressed: " + oPunchToolFeature.Suppressed
break ;
Case Else
373Programming Inventor in C#
(C) 2021 Owen F Ransen
Debug.WriteLine ( "Non Sheetmetal Feature: " + oFeature.Name Debug.WriteLine ( " Adaptive: " + oFeature.Adaptive Debug.WriteLine ( " Face Count: " + oFeature.Faces.Count Debug.WriteLine ( " HealthStatus: " + oFeature.HealthStatus Debug.WriteLine ( " RangeBox: (" + Format(oFaceFeature.RangeBox.MinPoint.X, "0.00000") + ", " + Format(oFaceFeature.RangeBox.MinPoint.Y, "0.00000") + ", " + Format(oFaceFeature.RangeBox.MinPoint.Z, "0.00000") + ")-(" + Format(oFaceFeature.RangeBox.MaxPoint.X, "0.00000") + ", " + Format(oFaceFeature.RangeBox.MaxPoint.Y, "0.00000") + ", " + Format(oFaceFeature.RangeBox.MaxPoint.Z, "0.00000") + ")" Debug.WriteLine ( " Suppressed: " + oFeature.Suppressed
break ;
} NextEnd Sub
13.28 Direction of a workaxis
Yes, axes have a direction. I personally don't know of a way to viewthat orientation outside of viewing those arrows while making aconstraint - maybe somebody else does.
374 Autodesk Inventor Programming in C++ by Owen Ransen
(C) 2021 Owen F Ransen
In the API, you can drill down and get the direction of the axis as avector. (workaxis.line.direction)
See also this.
13.29 HoleFeature HoleFeatureProxy C#
To find the position of a hole which is in a part which is in anassembly you must get hold of the hole feauture's proxy.
The proxy will give you the position of the hole in assemblycoordinates.
This function adds a fixed axis based on the position of a hole:
public static void AddFixedTest (){
if (!CurrentDocIsAssembly()){
MessageBox.Show("Not an assembly");
375Programming Inventor in C#
(C) 2021 Owen F Ransen
return;}
AssemblyDocument AsmDoc = m_Inventor.ActiveDocument as AssemblyDocument;AssemblyComponentDefinition AsmDef = AsmDoc.ComponentDefinition;ComponentOccurrences OccList = AsmDoc.ComponentDefinition.Occurrences;
ComponentOccurrence SpallaOcc = null;
// Find a component we know to contain "Hole7"foreach (ComponentOccurrence ThisOcc in OccList){
Debug.WriteLine("Found " + ThisOcc.Name);
// Get "30084896" only (not "30084896:2") by stripping off all the trailing characters....string sCode = ThisOcc.Name.Substring(0, 8);if (sCode == "30084896"){
SpallaOcc = ThisOcc;break;
}}
if (SpallaOcc == null){
MessageBox.Show("Spalla not found");return;
}
// The definition contains the list of holes...PartComponentDefinition SpallaDef = (PartComponentDefinition)SpallaOcc.Definition;
Debug.WriteLine("The spalla has " + SpallaDef.Features.HoleFeatures.Count + " hole features");
// Get it directly and hope it is thereHoleFeature Hole7 = SpallaDef.Features.HoleFeatures["Hole7"] ;
// CreateGeometryProxy needs an Object parameterObject Hole7ProxyObj = null;
// Create the proxy of the hole...SpallaOcc.CreateGeometryProxy(Hole7, out Hole7ProxyObj);
// Having created the general proxy cast it to a HoleFeatureProxy...HoleFeatureProxy Hole7Proxy = (HoleFeatureProxy)Hole7ProxyObj;
Debug.WriteLine ("Hole7 has " + Hole7Proxy.Faces.Count.ToString() + " faces");
376 Autodesk Inventor Programming in C++ by Owen Ransen
(C) 2021 Owen F Ransen
foreach (Face ThisHoleFace in Hole7Proxy.Faces){
if (ThisHoleFace.SurfaceType == SurfaceTypeEnum.kCylinderSurface){
Cylinder faceCyl = (Cylinder)ThisHoleFace.Geometry;StringBuilder sb = new StringBuilder("Cylinder In FaceFeature:" + "\r\n");Point centerPt = faceCyl.BasePoint;UnitVector axisVector = faceCyl.AxisVector;sb.Append("Center Point: X = " + Math.Round(centerPt.X, 4) + " Y = " + Math.Round(centerPt.Y, 4) + " Z = " + Math.Round(centerPt.Z, 4) + "\r\n");sb.Append("Axis: X = " + Math.Round(axisVector.X, 4) + " Y = " + Math.Round(axisVector.Y, 4) + " Z = " + Math.Round(axisVector.Z, 4));
Debug.WriteLine(sb.ToString());
AsmDef.WorkAxes.AddFixed(centerPt, axisVector);}
}}
This also illustrates getting a workaxis from a hole feature by uinsgthefaces of the hole.
There is a problem, being fixed the axis will not move if you move thepart.
13.30 Items in lists by string
Here are 2 different ways of doing the same thing, i.e. getting aHoleFeature by its text name:
// Get it directly and hope it is there HoleFeature Hole7 = SpallaDef.Features.HoleFeatures["Hole7"] ;
or
// Look for it, Hole7 remains null if not found HoleFeature Hole7 = null; foreach (HoleFeature ThisHole in
377Programming Inventor in C#
(C) 2021 Owen F Ransen
SpallaDef.Features.HoleFeatures) { if (ThisHole.Name == "Hole7") { Hole7 = ThisHole; break; } } if (Hole7 == null) { return; }
13.31 Constrain work axes C#
Here is how to constrain two work axes of two parts within anassembly
public static void WorkAxisMateTest() { if (!CurrentDocIsAssembly()) { MessageBox.Show("Non è un assieme"); return; } AssemblyDocument AsmDoc = m_Inventor.ActiveDocument asAssemblyDocument; AssemblyComponentDefinition AsmDef = AsmDoc.ComponentDefinition;
ComponentOccurrences OccsList = AsmDef.Occurrences; ComponentOccurrence SpallaOcc= null, FinPackOcc=null;
foreach (ComponentOccurrence Occ in OccsList) { string sComponentName = Occ._DisplayName.Substring(0, 8);
if ("30084897" == sComponentName) { SpallaOcc = Occ; }
if ("30095817" == sComponentName) { FinPackOcc = Occ; } }
378 Autodesk Inventor Programming in C++ by Owen Ransen
(C) 2021 Owen F Ransen
if ((SpallaOcc == null) || (FinPackOcc == null)) { MessageBox.Show("Manca spalla e o finpack"); return; }
try { PartComponentDefinition SpallaCompDef =(PartComponentDefinition)SpallaOcc.Definition; PartComponentDefinition FinPackCompDef =(PartComponentDefinition)FinPackOcc.Definition;
WorkAxis WASpalla = SpallaCompDef.WorkAxes["AsseAltoSinistra"]; WorkAxis WAFinPack = FinPackCompDef.WorkAxes["AsseAltoSinistra"];
// CreateGeometryProxy needs an Object parameter Object SpallaAxisProxyObj = null; Object FinPackAxisProxyObj = null;
// Create the proxies ... SpallaOcc.CreateGeometryProxy(WASpalla, outSpallaAxisProxyObj); FinPackOcc.CreateGeometryProxy(WAFinPack, outFinPackAxisProxyObj);
WorkAxisProxy WASpallaProxy =(WorkAxisProxy)SpallaAxisProxyObj; WorkAxisProxy WAFinPackProxy =(WorkAxisProxy)FinPackAxisProxyObj;
AsmDef.Constraints.AddMateConstraint(WASpallaProxy,WAFinPackProxy,0.0);
} catch (Exception Ex) { MessageBox.Show("Non sono risucito a fare il vincolo tra assi" + Ex.Message); } }
text here.
379Programming Inventor in C#
(C) 2021 Owen F Ransen
13.32 Constrain work things of a part to the work things of thecontaining assembly
You can do it, but remember that you do not need a proxy at theassembly level. You need a proxy for the part because it can movearound inside the assembly, but the assembly is, of course, fixed.
// A constraint between object B and a workplane in an assembly WorkPlaneA = m_AsmDef.WorkPlanes[m_iAsmObj]; // m_iAsmObj will be 1 2 or 3 probably
ComponentDefinition GenDefB = m_OccB.Definition; if (GenDefB.Type == ObjectTypeEnum.kAssemblyComponentDefinitionObject) { AssemblyComponentDefinition AsmDefB = (AssemblyComponentDefinition)m_OccB.Definition; WorkPlaneB = AsmDefB.WorkPlanes[m_iWorkObjB]; } else { // Assume a Part PartComponentDefinition PartDefB = (PartComponentDefinition)m_OccB.Definition; WorkPlaneB = PartDefB.WorkPlanes[m_iWorkObjB]; }
// CreateGeometryProxy needs an Object parameter object ProxyObjB = null; m_OccB.CreateGeometryProxy(WorkPlaneB, out ProxyObjB); WorkPlaneProxy WorkAxisBProxy = (WorkPlaneProxy)ProxyObjB;
if (m_eCostraintType == Type_e.eMate) { MateConstraint NewCons = null; // Here I use the workplane directly, in the asm, so no need for a proxy NewCons = m_AsmDef.Constraints.AddMateConstraint(WorkPlaneA, WorkAxisBProxy, 0.0); if (m_mmMaxOffset > 0.0) { NewCons.ConstraintLimits.MaximumEnabled = true; NewCons.ConstraintLimits.Maximum.Value = m_mmMaxOffset / 10.0; // Set as cm not mm } NewCons.Name = sName; } else { FlushConstraint NewCons; // Here I use the workplane directly, in the asm, so no need for a proxy NewCons = m_AsmDef.Constraints.AddFlushConstraint(WorkPlaneA, WorkAxisBProxy, 0.0); if (m_mmMaxOffset > 0.0) { NewCons.ConstraintLimits.MaximumEnabled = true;
380 Autodesk Inventor Programming in C++ by Owen Ransen
(C) 2021 Owen F Ransen
NewCons.ConstraintLimits.Maximum.Value = m_mmMaxOffset / 10.0; // Set as cm not mm } NewCons.Name = sName; }
If you see what I mean.
13.33 Bounding box of a part
Here is how to do it, make sure you use the ref keyword in the callthough:
PartDocument EndPlateDoc =CInvHelp.OpenPart(sEndPlateFullFileName, out PartDef);
Box BBox = PartDef.RangeBox;
double[] Mins = new double[3]; double[] Maxes = new double[3]; BBox.GetBoxData(ref Mins, ref Maxes);
for (int i = 0; i < 3; i++) { Debug.Write(Mins[i].ToString()); Debug.Write(" , "); Debug.Write(Maxes[i].ToString()); Debug.Write(" , "); }
These will be in native units, so normally cm.
13.34 Matrix Vector and SetTranslation, C#
Here is an example of how to use them:
// Create the default matrix... Matrix PosMat = TransGeom.CreateMatrix(); Vector DistribPos = TransGeom.CreateVector();
Point Origin = TransGeom.CreatePoint(0, 0, 0); Vector VectorAxis = TransGeom.CreateVector(1, 0, 0); PosMat.SetToRotation(-Math.PI/2.0, VectorAxis,Origin);
381Programming Inventor in C#
(C) 2021 Owen F Ransen
DistribPos.X = -20.0; // front view verticalpositioning, may change DistribPos.Y = 15.0; // how far from the spalla mainplane, may change DistribPos.Z = -mmEndPlateWidth/10.0; // positionnear center of double battery PosMat.SetTranslation(DistribPos);
Remember that SetTranslation will want cm, not mm.
13.35 WorkPlane orientation in C#
Here is some code which gets the a named WorkPlane in a part:
string sEndPlateFullFileName =GetPartFullFileName(sEndPlateCode); PartComponentDefinition PartDef = null; PartDocument EndPlateDoc =CInvHelp.OpenPart(sEndPlateFullFileName, out PartDef);
WorkPlane EndPlatePlane = PartDef.WorkPlanes["EndPlatePlane"];
// Point WPOrigin = null ; UnitVector XAxis = null; UnitVector YAxis = null;
EndPlatePlane.GetPosition(out _, out XAxis, outYAxis);
string sXaxis = string.Format("XAxis {0:0.0} {1:0.0}{2:0.0}", XAxis.X, XAxis.Y, XAxis.Z); Debug.WriteLine(sXaxis);
string sYaxis = string.Format("YAxis {0:0.0} {1:0.0}{2:0.0}", YAxis.X, YAxis.Y, YAxis.Z); Debug.WriteLine(sYaxis);
382 Autodesk Inventor Programming in C++ by Owen Ransen
(C) 2021 Owen F Ransen
And here are two examples of what those two vectors mean:
385Programming Inventor in C#
(C) 2021 Owen F Ransen
13.36 Standard WorkAxes in C#
Here is some code to help you along:
//base work axes
WorkAxis XAxis = oAssyDef.WorkAxes[1];
WorkAxis YAxis = oAssyDef.WorkAxes[2];
WorkAxis ZAxis = oAssyDef.WorkAxes[3];
But you would be better to define something like this:
// These help to get at workplanes WorkPlanes[]
public const int ikYZPlaneNum = 1;
public const int ikXZPlaneNum = 2;
public const int ikXYPlaneNum = 3;
// These help to get at workaxes WorkAxes[]
public const int ikXAxisNum = 1;
public const int ikYAxisNum = 2;
public const int ikZAxisNum = 3;
13.37 Constrain a part to an assembly level work axis
Here's how to create a workaxis at assembly level and constrain it toa hole.
386 Autodesk Inventor Programming in C++ by Owen Ransen
(C) 2021 Owen F Ransen
This is the VB version, when I have time I'll do the C# version
Imports System.Runtime.InteropServicesImports Inventor
387Programming Inventor in C#
(C) 2021 Owen F Ransen
Class MainWindow ' For this to work you need a part open in the assembly andthe part needs to have a t least one hole in it Private Sub Button_Click(sender As Object, e AsRoutedEventArgs)
Dim ThisApp As Inventor.Application Dim oCylGeom As Cylinder Dim oWAxis As WorkAxis
' To get this you need .NET framework, not just .NET ThisApp = Marshal.GetActiveObject("Inventor.application")
If ThisApp.ActiveDocumentType <>DocumentTypeEnum.kAssemblyDocumentObject Then MsgBox("An Assembly Document must be active for thisto work. Exiting.", vbOKOnly + vbCritical, "WRONG DOCUMENT TYPE") Exit Sub End If
Dim oADoc As AssemblyDocument = ThisApp.ActiveDocument Dim oADef As AssemblyComponentDefinition =oADoc.ComponentDefinition Dim oComp As ComponentOccurrence =oADef.Occurrences.Item(1) Dim oPDoc As PartDocument = oComp.Definition.Document Dim oPDef As PartComponentDefinition =oPDoc.ComponentDefinition If oPDef.Features.HoleFeatures.Count = 0 Then MsgBox("No holes") Exit Sub End If
Dim oHole As HoleFeature =oPDef.Features.HoleFeatures.Item(1)
'oHole.HoleCenterPoints 'could likely use these too Dim oCylFace As Face = oHole.SideFaces.Item(1) If oCylFace.SurfaceType =SurfaceTypeEnum.kCylinderSurface Then Dim oCylFaceProxy As FaceProxy = Nothing oComp.CreateGeometryProxy(oCylFace, oCylFaceProxy)
388 Autodesk Inventor Programming in C++ by Owen Ransen
(C) 2021 Owen F Ransen
oCylGeom = oCylFaceProxy.Geometry Dim oPoint As Inventor.Point = oCylGeom.BasePoint Dim oAxis As UnitVector = oCylGeom.AxisVector oWAxis = oADef.WorkAxes.AddFixed(oPoint, oAxis, False) oWAxis.Name = "ASM_WORK_AXIS"
Dim oMConst1 As MateConstraint =oADef.Constraints.AddMateConstraint2(oWAxis, oCylFaceProxy, 0,InferredTypeEnum.kInferredLine, InferredTypeEnum.kInferredLine,MateConstraintSolutionTypeEnum.kAlignedSolutionType) oMConst1.Name = "ASM_WORK_AXIS_CONSTRAINT"
Else MsgBox("Hole's first side face was not a Cylinder.Exiting.", , "") Exit Sub End If
End SubEnd Class
So that workaxis is at assembly level but constrainted to a hole in apart. You can constrain further things to that workaxis...
389Programming Inventor in C#
(C) 2021 Owen F Ransen
13.38 Create an assembly document C#
This code creates a new assembly and sets the measurement unitsto be mm
public static AssemblyDocument CreateNewAssembly() { try { // Get the list of documents currentlyopen inventor Documents DocList =m_Inventor.Documents;
FileManager FileMan =
390 Autodesk Inventor Programming in C++ by Owen Ransen
(C) 2021 Owen F Ransen
m_Inventor.FileManager;
string sTemplateFile =FileMan.GetTemplateFile(DocumentTypeEnum.kAssemblyDocumentObject, SystemOfMeasureEnum.kMetricSystemOfMeasure); //Make sure metric units
// Create the doc and get hold of it... AssemblyDocument NewAsmDoc =(AssemblyDocument)DocList.Add(DocumentTypeEnum.kAssemblyDocumentObject); NewAsmDoc.UnitsOfMeasure.LengthUnits =UnitsTypeEnum.kMillimeterLengthUnits; // make sure mmunits
return NewAsmDoc; }
catch (Exception Ex) { MessageBox.Show("Create new assemblyfailed, " + Ex.Message); return null; } }
392 Autodesk Inventor Programming in C++ by Owen Ransen
(C) 2021 Owen F Ransen
13.39 Listing the profiles of a face in C#
Look at this sheet metal:
Although it could be shown as a single face it is in fact 2 faces. Itprobably depends on how t was constructed. Anyway this code willlist the two profiles (if they are made of LineSegment2d:
public static void Test2 () { PartDocument PartDoc; try {
393Programming Inventor in C#
(C) 2021 Owen F Ransen
PartDoc = (PartDocument)m_Inventor.ActiveDocument as PartDocument; if (PartDoc == null) { MessageBox.Show("This is not a part document"); return; } } catch { MessageBox.Show ("not a part doc"); return; }
PartComponentDefinition PartDef = PartDoc.ComponentDefinition; PartFeatures FeatsList = PartDef.Features;
foreach (PartFeature ThisFeature in FeatsList) { if (ThisFeature.Type == ObjectTypeEnum.kCutFeatureObject) { CutFeature CutFeature = (CutFeature)ThisFeature; ProfilePath TheProfile = CutFeature.Definition.Profile[1]; ProfileEntity Ent = TheProfile[1];
Debug.WriteLine ("Profile ent " + Ent.ToString() + " " + Ent.CurveType.ToString());
if (Ent.CurveType == Curve2dTypeEnum.kCircleCurve2d) { Circle2d Circle = (Circle2d)Ent.Curve; Debug.WriteLine(" ...is a circle of radius " + Circle.Radius.ToString()); } } else if (ThisFeature.Type == ObjectTypeEnum.kFaceFeatureObject) { FaceFeature FaceFeat = (FaceFeature)ThisFeature; Debug.WriteLine("FaceFeature <" + FaceFeat.Name + "> has " + FaceFeat.Faces.Count.ToString() + " faces");
Debug.WriteLine(" the profile has " + FaceFeat.Definition.Profile.Count.ToString() + " objects");
foreach (ProfilePath ThisPath in FaceFeat.Definition.Profile) { Debug.WriteLine(" this path the profile has " + ThisPath.Count.ToString() + " entities");
foreach (ProfileEntity ThisEnt in ThisPath) { if (ThisEnt.CurveType == Curve2dTypeEnum.kLineSegmentCurve2d) { LineSegment2d Line2d = (LineSegment2d)ThisEnt.Curve;
394 Autodesk Inventor Programming in C++ by Owen Ransen
(C) 2021 Owen F Ransen
string sX0 = string.Format("{0,8:0.00}", Line2d.StartPoint.X); string sY0 = string.Format("{0,8:0.00}", Line2d.StartPoint.Y); string sX1 = string.Format("{0,8:0.00}", Line2d.EndPoint.X); string sY1 = string.Format("{0,8:0.00}", Line2d.EndPoint.Y);
Debug.WriteLine(" LinSeg, X:" + sX0 + " Y:" + sY0 + " --> X:" + sX1 + " Y:" + sY1); } } }
// Un false this to see even more detail#if false Faces FacesList = FaceFeat.Faces; // Face BiggestFace = null;
foreach (Face ThisFace in FacesList) { Debug.WriteLine(" this face has vertices: " + ThisFace.Vertices.Count.ToString() + " (feature: " + FaceFeat.Name + ")");
foreach (Vertex v in ThisFace.Vertices) { Point p = v.Point; Debug.WriteLine(" " + p.X.ToString() + " " + p.Y.ToString() + " " + p.Z.ToString()); } }#endif } else { Debug.WriteLine("This feature is a " + ThisFeature.Type.ToString()); } } }
And the output will look like this:
FaceFeature <Face1> has 3 faces the profile has 1 objects this path the profile has 4 entities LinSeg, X: 0,00 Y: 0,00 --> X: -53,30 Y: 0,00 LinSeg, X: -53,30 Y: 0,00 --> X: -53,30 Y: -53,00 LinSeg, X: -53,30 Y: -53,00 --> X: 0,00 Y: -53,00 LinSeg, X: 0,00 Y: -53,00 --> X: 0,00 Y: 0,00FaceFeature <Face3> has 1 faces the profile has 1 objects this path the profile has 4 entities LinSeg, X: 8,05 Y: 0,00 --> X: 8,05 Y: -3,50 LinSeg, X: 8,05 Y: -3,50 --> X: 52,90 Y: -1,90
395Programming Inventor in C#
(C) 2021 Owen F Ransen
LinSeg, X: 52,90 Y: -1,90 --> X: 52,90 Y: 0,00 LinSeg, X: 52,90 Y: 0,00 --> X: 8,05 Y: 0,00
...and shows that there are two FaceFeatures.
13.40 List all planes in a part, C#
There are always the first three planes which can be accessed by a 1based index. Other user work planes are added from 4 onwards:
In code you can access all the planes in a part like this:
396 Autodesk Inventor Programming in C++ by Owen Ransen
(C) 2021 Owen F Ransen
PartDocument PartDoc;try{
PartDoc = (PartDocument)m_Inventor.ActiveDocument as PartDocument;if (PartDoc == null){
MessageBox.Show("This is not a part document");return;
}}catch{
MessageBox.Show("not a part doc");return;
}
PartComponentDefinition PartDef = PartDoc.ComponentDefinition;WorkPlanes WPList = PartDef.WorkPlanes;
int iPlaneNumber = 1;foreach (WorkPlane ThisPlane in WPList){
Debug.WriteLine("ThisPlane is called <" + ThisPlane.Name + "> Plane number = " + iPlaneNumber.ToString());WorkPlane Plane1 = WPList[iPlaneNumber];Debug.WriteLine("Plane <" + Plane1.Name + "> number = " + iPlaneNumber.ToString());iPlaneNumber++;
}
This will give you output like this:
ThisPlane is called <YZ Plane> Plane number = 1Plane <YZ Plane> number = 1ThisPlane is called <XZ Plane> Plane number = 2Plane <XZ Plane> number = 2ThisPlane is called <XY Plane> Plane number = 3Plane <XY Plane> number = 3ThisPlane is called <PianoSpalla> Plane number = 4Plane <PianoSpalla> number = 4
Notice that 4th plane, the first user plane.
You could use something like this:
// These help to get at workplanes WorkPlanes[]
public const int ikYZPlaneNum = 1;
397Programming Inventor in C#
(C) 2021 Owen F Ransen
public const int ikXZPlaneNum = 2;
public const int ikXYPlaneNum = 3;
// These help to get at workaxes WorkAxes[]
public const int ikXAxisNum = 1;
public const int ikYAxisNum = 2;
public const int ikZAxisNum = 3;
13.41 Get a WorkPlane by name
You can use square brackets and the name:
WorkPlane EndPlatePlane = PartDef.WorkPlanes["EndPlatePlane"];
You'll probably get an exception if the plane does not exist
13.42 kReferenceFeatureObject is a derived part
If you get a feature in a part it might be a reference to another part:
else if (ThisFeature.Type ==ObjectTypeEnum.kReferenceFeatureObject) { ReferenceFeature RefFeat = (ReferenceFeature)ThisFeature;
Debug.WriteLine("kReferenceFeatureObject called " +RefFeat.Name);
ReferenceComponents RefComps =PartDef.ReferenceComponents;
DerivedPartComponent DerivPartComp =RefComps.DerivedPartComponents[1];
I have not been able to really go deeper into this yet.
398 Autodesk Inventor Programming in C++ by Owen Ransen
(C) 2021 Owen F Ransen
13.43 Reading values from an iPart table in C#
Here is a big example:
static public C3dCctData Get3dCctData (AssemblyComponentDefinitionAsm3dCctDef) { AssemblyDocument CctDoc = (AssemblyDocument)Asm3dCctDef.Document; string sGeom = CInvHelp.GetCustomiProperty(CctDoc,"CC_FIN_GEOMETRY"); double mmSporgenza = 0.0; ComponentOccurrences Occurences = Asm3dCctDef.Occurrences;
// Find the sporgenza looking at the forcelle or tubes. // These are iParts and so we need to look at their tables... foreach (ComponentOccurrence ThisOcc in Occurences) { // Is this occurrence a part? ComponentDefinition ThisDef = ThisOcc.Definition; if (ThisDef.Type ==ObjectTypeEnum.kPartComponentDefinitionObject) { // This is a part... PartComponentDefinition PartDef =(PartComponentDefinition)ThisDef; PartDocument PartDoc = (PartDocument)PartDef.Document;
AutoBatSupp.Log.WriteLn(CLog.Type_e.ekLog, " lookingat:", PartDoc.DisplayName);
// Get the SAP code for this part... string sPartSapCode = PartDoc.DisplayName.Substring(0,AutoBatSupp.ikNumSapChars);
// Is this an iPart? if (PartDef.IsiPartMember) { // This is an iPart member, which I want to find outmore about... iPartMember Member = PartDef.iPartMember; iPartFactory Factory = Member.ParentFactory;
AutoBatSupp.Log.WriteLn(CLog.Type_e.ekLog, " is amember, the factory has ", Factory.TableRows.Count.ToString(), " columns");
// Look over all columns to find the one we arelooking for... int iColIndex = 0; // Errore value int i = 1; foreach (iPartTableColumn Col in Factory.TableColumns) { if (Col.Heading == "SporgLatoCurve") {
399Programming Inventor in C#
(C) 2021 Owen F Ransen
iColIndex = i; break; } i++; }
if (iColIndex > 0) { // So, we know in which *column* to get thesporgenza from
// Loop over all the rows to find the one whichcorresponds to our part iPartTableRows Rows = Factory.TableRows; foreach (iPartTableRow Row in Rows) { iPartTableCell SapCodeCell = Row[1]; string sThisSapCode = SapCodeCell.Value; if (sThisSapCode == sPartSapCode) { iPartTableCell SporgenzaCell =Row[iColIndex]; string sCellValue =AutoBatSupp.GetCleanNumberString(SporgenzaCell.Value); // Convert from "20,00mm" to "20.00" AutoBatSupp.Log.WriteLn(CLog.Type_e.ekLog, " cell is ", sCellValue); if (!double.TryParse(sCellValue,NumberStyles.Number, CultureInfo.InvariantCulture, out mmSporgenza)) { AutoBatSupp.Log.WriteLn(CLog.Type_e.ekErr, " could not get sporgenza ",mmSporgenza.ToString(), " from ", sCellValue); } else { AutoBatSupp.Log.WriteLn(CLog.Type_e.ekLog, " sporgenza is ",mmSporgenza.ToString()); break; // finished. } } } } } } }
if (mmSporgenza == 0.0) { AutoBatSupp.Log.WriteLn(CLog.Type_e.ekErr, "Could not findsporgenza parameter"); }
400 Autodesk Inventor Programming in C++ by Owen Ransen
(C) 2021 Owen F Ransen
// Compose all the data into a single object C3dCctData CctData = new C3dCctData { m_sGeom = sGeom, m_mmSporgenza = mmSporgenza };
return CctData;
Enter topic text here.
14 Using Inventor manually
14.1 Parallel constraint, not coplanar
You can make planes be parallel but not coplanar by using the Limitstab...
401Using Inventor manually
(C) 2021 Owen F Ransen
You'll have to experiment with which limits work. If the objects aresmall you can use, for example, 1000mm in the Maximum.
See also software wise.
You can achieve the same result using angular constraints...
.
14.2 BOMs and Part Lists
14.2.1 BOM vs Parts List
BOM can be accessed from Assembly and Drawing while Parts List isa Drawing only table.
In general a BOM cannot be changed, it is based on the actualassembly and rows cannot be added. But for example counts can be
402 Autodesk Inventor Programming in C++ by Owen Ransen
(C) 2021 Owen F Ransen
changed by making them static.
In the parts list you can add rows.
14.2.2 Adding a flat parts list in a drawing
Add the BOM into the assembly. See here and here. In the BOMselect Parts Only.
Create the drawing with that assembly as the base view.
Go to Annotate tab Parts List icon. In the Parts List dialog select BOMView Parts Only item:
14.2.3 BOM Bill of materials
To find the settings of the BOM go into the document settings of theassembly or part and click on the BOM tab.
To get to the BOM itself:
403Using Inventor manually
(C) 2021 Owen F Ransen
The parts list is derived from the BOM, but is not the same thing. Itseems to be closer to the metal. I think you can't do much with theBOM, whereas the parts list is more flexible.
Components can be1. Normal2. Phantom, like screws nuts washers, ignored by the BOM but used
in the mass calculations.3. Referenced, these are not real components, but are present to
help the drawing construction. Ignored by BOM and masscalculations.
4. Purchased, the component is a single BOM line5. Inseperable, made of parts, but of parts which cannot be separated
from each other
404 Autodesk Inventor Programming in C++ by Owen Ransen
(C) 2021 Owen F Ransen
See also substitution.
14.2.4 Remove something from a Parts List
Double click on the parts list in the drawing, that will bring up the partslist dialog list box. Right click on the component, and turn of visibility.
14.2.5 Parts list modification
Add a parts list to a drawing IDW like this (save the drawing first):
Once you have added a parts list you can modify it, even substitutingsome columns for other columns, Parts List Column Substitution:
405Using Inventor manually
(C) 2021 Owen F Ransen
Note that the parts list is obtained from the BOM but is not the samething.
14.2.6 Parts Only (disabled) problem
If you get the BOM dialog with Parts Only (disabled) all you have todo is enable them using the magnifying glass:
406 Autodesk Inventor Programming in C++ by Owen Ransen
(C) 2021 Owen F Ransen
14.2.7 Virtual components
Virtual components are good for adding quantities of paint or solderor padding ext. They appear in the BOM. They can only be insertedinto an assembly, not into a part.
You create them like this:
407Using Inventor manually
(C) 2021 Owen F Ransen
They have that white cube icon in the assembly.
Now here is how you can set the component to hold data aboutweight (for example). Create a user parameter which contains thedata you need, then...
408 Autodesk Inventor Programming in C++ by Owen Ransen
(C) 2021 Owen F Ransen
Now the component will appear in the BOM like this:
409Using Inventor manually
(C) 2021 Owen F Ransen
If this does not work in your situation you can also try this technique.
410 Autodesk Inventor Programming in C++ by Owen Ransen
(C) 2021 Owen F Ransen
14.2.8 Parts List Style (Default)
You set it like this:
It is all a bit of a mystery inside an enigma:
412 Autodesk Inventor Programming in C++ by Owen Ransen
(C) 2021 Owen F Ransen
See and understand also this:
413Using Inventor manually
(C) 2021 Owen F Ransen
14.2.9 Alternative to a virtual component in a BOM
If you want to add liquids or solder or other materials to yourassembly you can use virtual components. This generally works, butsometimes, for various reasons, this is not the best way.
So, instead, you can create an IPT and say it is counted not as anitem but as a quantity, milligrams, or mm or whatever. Look at thequantity for GA1234 in the parts list below:
414 Autodesk Inventor Programming in C++ by Owen Ransen
(C) 2021 Owen F Ransen
It says the quantity is 14 grams. (The other quantities in the list aboveare counts of the number of IPTs in the assembly.)
Create the IPT which you want to contain your quantity and which youwant to appear in the BOM and Parts List. In the example belowGA1234.IPT has had its BOM settings set to grams:
The next step is to make that parts entry in the BOM "Static", whichmeans you can write whatever number you want in there, it is notcalculated:
415Using Inventor manually
(C) 2021 Owen F Ransen
Finally, if you want a parts list as well as a BOM, be sure to use QTYas one of the columns. As you design your parts list choose QTY asshown below:
416 Autodesk Inventor Programming in C++ by Owen Ransen
(C) 2021 Owen F Ransen
14.3 iParts
14.3.1 iParts general info
iParts work with parametric parts.
Steps to create an iPart, a tube for example:
1. Create a new part.2. In the sketch add a circle3. Add a dimension to the circle and in the tiny mm box type
Diameter=204. End the sketch and extrude it.5. In the edit box for the extrusion type Length=50.6. Finish the sketch7. Now you have two model parameters named as you want as
Length and Diameter (instead of the default L0 and D0).8. You also have a tube which is 20 by 509. Now go into the Manage tab and click on the Create iPart icon. (if
grey disabled trying saving the file) 10.Now you can create a table of different sized tubes. Each row of
the table is called a Member.
417Using Inventor manually
(C) 2021 Owen F Ransen
14.3.2 iPart - standard vs custom
A standard iPart has parameter values which must be selected from apredefined list. e.g. part code corresponds to a record in a table. Therecord contains the parameters like angle and length to specify theiPart for that code.
A custom iPart allows you to write whatever values you want, not justselecting one of several fixed values from a list.
In the SDK there are two examples of iParts, one custom onestandard, in this directory...
C:\Users\Public\Documents\Autodesk\Inventor 2013\SDK\DeveloperTools\Samples\Data_Files
...you should find CustomFactory.ipt and StandardFactory.ipt.
14.3.3 iPart author
To get to the iPart Author click on the Create iPart icon in the Managetab.
You must have Excel installed for iParts to work.
14.3.4 iPart Member and PartNumber
As far as I can tell there is some confusion here. It seems thatMember is the key index into the table, and maybe PartNumber is adescriptive field. This confusion/duplication/feature is due to history.
So when creating iParts make sure that Member has the code of the
418 Autodesk Inventor Programming in C++ by Owen Ransen
(C) 2021 Owen F Ransen
object you are creating, like 34120009.
Why is a new column needed? It is because sometimes memberscan have the same Part Number. PN is just a user book-keepingattribute. We need a column with unique values.
In summary, the Member column has to be there. The cell values canbe changed but they have to be unique. Please do not delete orrelocate the column.
The Member also gives the name to any temporary files created bythe iPart factory.
The iPart also generates "children" files, which represent each of themembers of your table. These are files that you normally don't haveto do much with, as they are controlled by the table in the Factorypart. The file names for these child parts are controlled by theMember name from the table - hence, when you change the membernames, their file names will change. This (not the name of the factorypart) is what the warning message was referring to.
419Using Inventor manually
(C) 2021 Owen F Ransen
14.3.5 Custom iParts
Create your part normally, for example a cylinder with Diameter andLength dimensions.
420 Autodesk Inventor Programming in C++ by Owen Ransen
(C) 2021 Owen F Ransen
Clicking on the Create iPart icon you'll get the iPart Author dialog,right click on the Diameter column and select Custom ParameterColumn:
421Using Inventor manually
(C) 2021 Owen F Ransen
The diameter column will become purple. Do this with all the otherparameters to make the custom iPart:
When you place the custom iPart inside an assembly you'll be shownthis dialog, where you can change the values:
Here is an example of the 3 custom iPart cylinder instances inside anassembly:
422 Autodesk Inventor Programming in C++ by Owen Ransen
(C) 2021 Owen F Ransen
How to change parameters of an already created custom iPart.
14.3.6 Changing Custom Ipart Parameters
Once you have created a custom ipart you can change theparameters by Activating its table:
423Using Inventor manually
(C) 2021 Owen F Ransen
So here I'm changing the parameters of the"derived" object.
In the above screenshot the "source" object is Tubo-CHS-LHS-Custom.ipt
424 Autodesk Inventor Programming in C++ by Owen Ransen
(C) 2021 Owen F Ransen
14.3.7 Suppression of features parametrically using the iPart Author
You need to drag the feature into the right hand panel of theSuppression tab, then the accepted values inside the parameter editbox is C or S. (Computer or Suppress).
14.3.8 Changing from iPart back to normal part
If you have an iPart with a table and you want to get back to a normalpart without a table, open the iPart, right click on the table, and select"Delete"
425Using Inventor manually
(C) 2021 Owen F Ransen
1. You'll get a warning about turning the file back into a normal part. 2. Remember to set the parameters to those that you want before
removing the table.3. Do this on a copy of you want to keep the original tabulare iPart.
14.3.9 Custom column in an iPart table
Sometimes you want to add some text or a number into the iPart'stable which is not strictly connected to the geometry of the part. Youdo it like this:
· Open the table· Go to the Other tab· Click in the empty space· Insert the name of the extra column
426 Autodesk Inventor Programming in C++ by Owen Ransen
(C) 2021 Owen F Ransen
14.3.10 Create iPart icon is grey
This can happen if you have not saved the file recently.
14.4 Suppress and Level Of Detail
Apparently Suppress Part in assemblies is used to create a lighter filewhen drawing and manipulating, and is intimately connected withLOD (Level Of Detail).
When you calculate the mass you can do it with all parts or just theunsupressed parts.
14.5 Offset of a point
You can give a point an offset...
I'm a programmer/educator not a mechanical designer so please bearwith me. There is a flange constrained using a plane an axis and apoint:
427Using Inventor manually
(C) 2021 Owen F Ransen
I'd like to be able to move the flanged tube in by 10mm. I can do thisby increasing the offset on the point-point constraint to 10mm. If I use-10 it does not go in the other direction. Presumably the absolutevalue of the number is taken.
But what tells Inventor in which direction the offset (in a point to pointconstraint) should go?.
This described mate combination has two possible solutions. Duringmate creation you can control the result using BiasPointOne andBiasPointTwo arguments. When the mates are already created, youcan move with the occurrence via API or iProperties dialog. If youmove the occurrence near to the second possible solution, afterupdate the occurrence will be move to the nearest solution (thesecond one in this case).Tags (0)
14.6 Pack And Go
Here's something which sort of works...
Copy all the pieces from the Pack And Go area into the Inventorcache directory. You will have to decide whether to overwrite thevarious bits and pieces.
428 Autodesk Inventor Programming in C++ by Owen Ransen
(C) 2021 Owen F Ransen
Most components are in the "Area di Lavoro" or the Englishequivalent:
In some cases the main component is in the same directory, as in theabove example, in other cases the main component is in a higherlevel directory:
429Using Inventor manually
(C) 2021 Owen F Ransen
Once in the usual Inventor directory make sure all components arenot read-only then pen them and save them while having your normalproject setup (i.e. not the Pack And Go project which the componentsarrived with).
14.7 WorkAxes at assembly level
When you add a work axis at assembly level what you actually do isconstrain it to some feature of a part.
430 Autodesk Inventor Programming in C++ by Owen Ransen
(C) 2021 Owen F Ransen
Programmatically you can AddFixed, and they stay in that place inspace, unattached to any part feature.
14.8 Insert constraint
The insert (perno foro) constraint lines up two cylindrical features byusing their axes and two planes.
432 Autodesk Inventor Programming in C++ by Owen Ransen
(C) 2021 Owen F Ransen
...aligned puts the cylinder exactly on the surface aligning the twoaxes:
433Using Inventor manually
(C) 2021 Owen F Ransen
14.9 Faces as objects
You can create faces by extruding a profile with the correctproperties...
434 Autodesk Inventor Programming in C++ by Owen Ransen
(C) 2021 Owen F Ransen
14.10 Show hidden lines in a drawing manually
To show hidden lines in a 2D IDW drawing follow this:
435Using Inventor manually
(C) 2021 Owen F Ransen
14.11 Axis directions
It seems that it is better to use undirected axes constraint, eventhough each work axis does have a direction.
436 Autodesk Inventor Programming in C++ by Owen Ransen
(C) 2021 Owen F Ransen
So if you have a plane to plane constraint already in place you shouldchoose "undirected" axis constraint. I suppose it makes sensebecause who can tell which direction a hole or circular cut axis shouldgo...?
14.12 Creating folders in the browser manually
Select the objects in the browser and then context click and thenchoose "Add to New Folder"...
437Using Inventor manually
(C) 2021 Owen F Ransen
14.13 Construction lines in sketches
Construction lines help you create the profile to extrude, for example,but are not extruded themselves. You can flip lines from construction(dotted) to normal and back again using this icon:
438 Autodesk Inventor Programming in C++ by Owen Ransen
(C) 2021 Owen F Ransen
14.14 Formulas inside parameter settings
Here is an example which is the formula equivalent of this iLogic VBexample:
439Using Inventor manually
(C) 2021 Owen F Ransen
sign(RagColl - RagAtt) * sqrt(( RagColl * RagColl - RagAtt *RagAtt ) * sign(RagColl * RagColl - RagAtt * RagAtt))
It is very very important that the case is respected in the parameternames and the functions.
Here's how the thing would appear inside a part:
14.15 Explode a pattern
To make an object independent from its containing pattern right clickon the Element text odf the object, and choose "Independent".
440 Autodesk Inventor Programming in C++ by Owen Ransen
(C) 2021 Owen F Ransen
Once it is independent though all the constraints will be lost.
You can't remove the first object from a pattern, and you can't removean object from a pattern inside a pattern.
14.16 Assembly WorkPoints and Part WorkPoints
These are a bit different and so cannot be assumed to behave in thesame way. You cannot, in an assembly, create a WorkPoint from aSketchPoint. Autodesk says:
"Hi! Certainly, the behavior is not intuitive but there are technicalreasons behind it. Inventor assembly (except assembly features andweldment) is not history based like part. The advantage is to allowusers to structure the assembly and swap out components with ease.Work geometry is treated like a component. So, a workpoint or aworkplane or a workaxis is actually a component which can beconstrained to other geometry. Assembly level work geometry can be
441Using Inventor manually
(C) 2021 Owen F Ransen
adjusted by editing the constraint values. It is not like the workgeometry in a part as features.
However, assembly level sketch does have a sense of history likeassembly features. Allowing non-history based operation likeconstraining to act on history based object can lead to an unsolvablecycle. As a result, assembly level work geometry cannot beconstrained to an assembly sketch. There is room for improvementhere. At least, it should be made more apparent why this operation isblocked. I will work with project team to understand the behaviorbetter and see if the limitation can be removed."
The same presumably goes for WorkAxis and WorkPlane objects.
14.17 Erase pattern elements
It seems that you can suppress pattern elements, but not deletethem:
442 Autodesk Inventor Programming in C++ by Owen Ransen
(C) 2021 Owen F Ransen
14.18 Axis perpendicular to sketch point, how to
It is fairly easy, add the axes on a sketch point and parallel to (forexample) Z.
But remember that you may have to click on the Update icon if youchange some parameters:
445Using Inventor manually
(C) 2021 Owen F Ransen
14.19 Delete a dimension manually
14.20 Mass Volume Calculation
In the brower, on the part or assembly root, right click and selectiProperties from the menu. Then click on the Physical tab. You mayhave to recalculate. And you may want with or without suppressedparts.
14.21 Add a WorkPlane in an Assembly
Here is a function to to it based on the existing standard workplanesof an assembly:
bool AddFixedWorkPlaneInAsm (CComPtr<AssemblyComponentDefinition>& pAsmCompDef, // where the plane will be added const int ikPlaneIdx, // Which ofthe standard planes to base the new one on const double kOffsetMm, // Offset, const wchar_t* const pszPlaneName)
446 Autodesk Inventor Programming in C++ by Owen Ransen
(C) 2021 Owen F Ransen
// Name of the newly created plane{ gLogger.Printf (ekLogMsg,L"AddFixedWorkPlaneInAsm %d <%s>starting",ikPlaneIdx,pszPlaneName) ; // Get WorkPlanes CComPtr<WorkPlanes> pWorkPlanes ; HRESULT hRes = pAsmCompDef->get_WorkPlanes(&pWorkPlanes); if (FAILED(hRes)) { ShowCOMError (hRes,L"AFWPIA, get_WorkPlanes failed") ; return false ; }
// Get hold of one of the WorkPlanes. Valid indices are 1 2 3for standard workplanes CComPtr<WorkPlane> pAsmStdWorkPlane ; hRes = pWorkPlanes->get_Item(CComVariant(ikPlaneIdx),&pAsmStdWorkPlane); if (FAILED(hRes) || (pAsmStdWorkPlane==nullptr)) { ShowCOMError (hRes,L"AFWPIA, get_Item (workplane %d)failed",ikPlaneIdx) ; return false ; }
// Get the standard plane to use as a base for the offsetplane PlanePtr ThePlane = pAsmStdWorkPlane->GetPlane() ; PointPtr StdPlaneOrigin = ThePlane->RootPoint ;
CComPtr<TransientGeometry> pTransGeo = GetTransGeomPtr () ;
// Internally Inventor always uses cm, so convert... const double kOffsetInCm = kOffsetMm/10.0 ;
CComPtr<Point> pOrigin ; hRes = pTransGeom->CreatePoint (StdPlaneOrigin->X,StdPlaneOrigin->Y,StdPlaneOrigin->Z,&pOrigin); if (FAILED(hRes) || (pOrigin == nullptr)) { ShowCOMError (hRes,L"AFWPIA, could not create originpoint") ; return false ; }
CComPtr<UnitVector> uVector; CComPtr<UnitVector> yVector;
447Using Inventor manually
(C) 2021 Owen F Ransen
switch (ikPlaneIdx) { case gikXYPlaneIndex : pTransGeo->CreateUnitVector (1.0, 0.0, 0.0, &uVector); pTransGeo->CreateUnitVector (0.0, 1.0, 0.0, &yVector); pOrigin->PutZ (kOffsetInCm) ; break ;
case gikXZPlaneIndex : pTransGeo->CreateUnitVector (1.0, 0.0, 0.0, &uVector); pTransGeo->CreateUnitVector (0.0, 0.0, 1.0, &yVector); pOrigin->PutY (kOffsetInCm) ; break ;
case gikYZPlaneIndex : pTransGeo->CreateUnitVector (0.0, 1.0, 0.0, &uVector); pTransGeo->CreateUnitVector (0.0, 0.0, 1.0, &yVector); pOrigin->PutX (kOffsetInCm) ; break ;
default : gLogger.Printf (ekErrMsg,L"AFWPIA unhandled index:%d", ikPlaneIdx) ; // Do something anyway... pTransGeo->CreateUnitVector (1.0, 0.0, 0.0, &uVector); pTransGeo->CreateUnitVector (0.0, 1.0, 0.0, &yVector); // pOrigin->PutZ (kOffsetInCm) ; break ; }
CComPtr<WorkPlane> pOffsetWorkPlane; hRes = pWorkPlanes->AddFixed(pOrigin,uVector,yVector,VARIANT_FALSE,&pOffsetWorkPlane); if (FAILED(hRes) || pOffsetWorkPlane == nullptr) { ShowCOMError (hRes,L"AFWPIA, Could not AddFixed plane %d",ikPlaneIdx) ; return false ; }
448 Autodesk Inventor Programming in C++ by Owen Ransen
(C) 2021 Owen F Ransen
CComBSTR bstrName = CString (pszPlaneName) ; pOffsetWorkPlane->put_Name (bstrName) ;
gLogger.Printf (ekLogMsg,L"AddFixedWorkPlaneInAsm <%s> endingok",pszPlaneName) ;
return true ;}
Here's some other less flexible code:
HRESULT Result = NOERROR;
CLSID InvAppClsid; Result = CLSIDFromProgID (L"Inventor.Application", &InvAppClsid); if (FAILED(Result)) return;
CComPtr<IUnknown> pInvAppUnk; Result = ::GetActiveObject(InvAppClsid, NULL, &pInvAppUnk); if (FAILED(Result)) { _tprintf_s(_T("*** Could not get hold of an active Inventorapplication ***\n")); return ; }
CComPtr<Application> pInvApp; Result = pInvAppUnk->QueryInterface (__uuidof(Application), (void **)&pInvApp); if (FAILED(Result)) return ;
CComPtr<Document> oDoc; CComPtr<AssemblyDocument> pAssyDoc; Result = pInvApp->get_ActiveDocument(&oDoc); pAssyDoc = oDoc;
CComPtr<TransientGeometry> pTransGeo; Result = pInvApp->get_TransientGeometry(&pTransGeo);
CComPtr<Point> pt; Result = pTransGeo->CreatePoint(0, 0, -100,&pt);
CComPtr<UnitVector> xVector; Result = pTransGeo->CreateUnitVector(1,0, 0, &xVector);
CComPtr<UnitVector> yVector; Result = pTransGeo->CreateUnitVector(0, 1, 0, &yVector);
449Using Inventor manually
(C) 2021 Owen F Ransen
CComPtr<WorkPlane> wPlane;
Result = pAssyDoc->ComponentDefinition->WorkPlanes->AddFixed(pt,xVector,yVector, VARIANT_FALSE,&wPlane);
14.22 Add a feature to an existing pattern
You can add a feature to an existing pattern by simply editing it andwhen the dialog comes up (don't click in the dialog) hover the mouseover the feature you want to add (you'll see a + sign near the cursor).Then click on it.
NB: In the browser you must put the new features you want to add tothe pattern higher up than the pattern itself. The features you want toadd to the pattern must be considered to be created before thepattern itself.
450 Autodesk Inventor Programming in C++ by Owen Ransen
(C) 2021 Owen F Ransen
14.23 Add a point to the surface of a tube manually
The first step is to put a plane at the required height:
Put a sketch on that new plane, then project the geometry of the tubeonto the sketch. Draw a line and put a point at the intersection of thegeometry and the line.
14.24 General Note and text
You can add text to an Inventor document using the General Notefunction:
451Using Inventor manually
(C) 2021 Owen F Ransen
It looks like it always floats on the screen in a given quarter which youchoose.
14.25 Add an angular dimension
You select the Dimension icon and then select two lines.
The problem is that the standard axes are not considered lines, soyou have to add one manually before you can select it. Add a linealong the axis you want to use as the base for the angular dimension,in other words.
452 Autodesk Inventor Programming in C++ by Owen Ransen
(C) 2021 Owen F Ransen
14.26 Adding a Dimension in a sketch
The add dimension icons are in the constrain panel of the sketch tab.
For example...
Create a circle in Sketch mode and create a dimension in the Toolstab. Then click on the Parameters icon in the Manage tab. Now youcan change the name of the parameter from "d0" to, for example,"MainTubeDiam". So that parameter now controls the diameter of atube constructed on that sketch.
14.27 Application Options Settings
At empty startup go into the Tools tab and click on ApplicationOptions.
The files tab of this dialog lets you change various directories, likeyour default projects folder.
If you can't find an option in Application Options it is probably inDocument Settings (next to each other in the Tools ribbon). You canuse templates to make application wide document settings.
14.28 Backup options for Inventor files
This is an item in the project options. Select the project in the upperpane and select the Options branch in the lower pane.
The default setting for Old Versions To Keep is 1, keep one backup.You can set this to 2 3 4 or whatever.
453Using Inventor manually
(C) 2021 Owen F Ransen
14.29 Add-In automatic load suppression
The loading of Add-Ins can slow down the startup of Inventor, and ifyou don't need them you can stop them like this:
454 Autodesk Inventor Programming in C++ by Owen Ransen
(C) 2021 Owen F Ransen
14.30 Strange material problem
If you get a single solid object which has different materials on it usethe Clear All Overides on its properties:
455Using Inventor manually
(C) 2021 Owen F Ransen
The solid above is copper outside and steel inside, I don't know why.But the clear all overrides solves the problem.
14.31 Browser is missing! Get it back!
Go to View tab, User Interface icon.
14.32 Change material / color of a solid
Select the object in the browser, and then use the material combo atthe top of the window:
456 Autodesk Inventor Programming in C++ by Owen Ransen
(C) 2021 Owen F Ransen
14.33 Change the offset elevation of a plane
Double click on the plane:
457Using Inventor manually
(C) 2021 Owen F Ransen
and you'll get the edit box.
14.34 Changing home view setting
Go to the view you want to be the home view then right click on thehome view icon, the examine the menu which pops up.
Front Top Right is the default visibility of the cube for home view.
458 Autodesk Inventor Programming in C++ by Owen Ransen
(C) 2021 Owen F Ransen
You can choose to set the current view as fit to view or fixed distance.
14.35 Changing manipulator snap
Use the Document Settings in the Tools tab. Then choose theModelling tab, 3D Snap Spacing edit box.
14.36 Changing the default units
Use the application options to change the default template file:
You can also change this in the document options:
459Using Inventor manually
(C) 2021 Owen F Ransen
When programming Inventor internal units are fixed.
14.37 Completely and adequately constrained sketches
A sketch has dimensions and constraints. Here is how to addconstraints manually:
460 Autodesk Inventor Programming in C++ by Owen Ransen
(C) 2021 Owen F Ransen
The two red arrows show how to add a tangent constraint between aline and a circle.
The two green arrows show how to add a contraint between aWorkPoint and a line endpoint.Inadequatrely constrained objects are black.
The bottom right status bar in sketch mode tells you whether thesketch is fully constrained or not. It will either say Fully Contrained or N dimensions needed.
461Using Inventor manually
(C) 2021 Owen F Ransen
14.38 Constrain 2 pairs of axes
If you have a u-bend you have two axes in it, say AxisA and AxisB.These two axes have to be constrained to another two axes whichrepresent the tubes which the u-bend connects, say Axis1 and Axis2:
The problem is that although you can fix AxisA to be completelyconstrainged by Axis1, depending on the accuracy of the parts youmay not be able to constraing AxisB to Axis2. For example the inter-axis distance might be 25.0 on the u-bend but 25.06 between the twotubes.
You can get over this problem by changing the parameter in thesecond constraint. If you set it to 0.1mm, as shown above, it meansthat one of the axes rotates around the other with a radius of 0.1mm:
462 Autodesk Inventor Programming in C++ by Owen Ransen
(C) 2021 Owen F Ransen
In the first image above the Mate:12 (0,100) tells you the "radius""offset" of 0.1mm.
If you don't give this flexibility in a 4 axis construction you might get ayellow rectangle liks this:
Programatically here .
463Using Inventor manually
(C) 2021 Owen F Ransen
14.39 Constrain vertically and horizontally
Sometimes objects in sketches remain unconstrained (green objects)even though they are on axes. You need to constrain them probablyby the two constrain icons as shown below:
Here the green points are constrained with horizontal dimensions butnot vertically. The blue points are completely constrained.
465Using Inventor manually
(C) 2021 Owen F Ransen
14.40 Contact set
A contact set is a subset of points for calculating interference.
14.41 Contraints between 3D part objects
Move into the Assemble tab and click on the Constrain icon, seebelow:
466 Autodesk Inventor Programming in C++ by Owen Ransen
(C) 2021 Owen F Ransen
The screenshot above also illustrates the fact that constraints canhave names, apart from Mate:1 etc. Note George and Mildred.
3D object based constraints are generally at the level of assembly,and constraints "connect" parts within the assembly.
Click here for constraints and parts from a programmers point of view.
14.42 Crash when creating a new drawing
You may get this message:
467Using Inventor manually
(C) 2021 Owen F Ransen
It may be fixed, perhaps, by following the instructions above andchanging the hardware accelleration (inside Inventor) fromperformance to conservative.
14.43 Create a sketch by default on creating a new part
Use the Tools Application Options Part tab to select create x-y sketchautomatically.
14.44 Creating a big tube with holes in it
Start a new part and then a new sketch. Use the XY plane for yoursketch:
468 Autodesk Inventor Programming in C++ by Owen Ransen
(C) 2021 Owen F Ransen
While in sketch mode draw two circles on it, then exit the sketch:
469Using Inventor manually
(C) 2021 Owen F Ransen
Now extrude, you may have to select the "profile" as being the areabetween the two circles:
470 Autodesk Inventor Programming in C++ by Owen Ransen
(C) 2021 Owen F Ransen
In the browser select the yz plane and create a new sketch there:
472 Autodesk Inventor Programming in C++ by Owen Ransen
(C) 2021 Owen F Ransen
Now you have to put some points in the sketch which can be used ashole centers. To do this make sure that center point is highlighted likethis:
473Using Inventor manually
(C) 2021 Owen F Ransen
Now when you use the point command the points you make can beused as center points:
Putting 3 points in the yz sketch will look like this:
474 Autodesk Inventor Programming in C++ by Owen Ransen
(C) 2021 Owen F Ransen
Click on Finish Sketch, you'll return to the 3D part view. Now click onthe Hole icon and you'll get something like this:
14.45 Creating a drawing of an assembly or part
You need to have the assembly (or part) already open before you cancreate a drawing of it. And then, oddly enough, you have to create anew drawing using the file menu, and then specify the assembly.
1. Use the "file" new drawing command, you'll get a piece of paper onthe screen.
2. Right click on the paper and select "Base View"3. Choose various parameters:
475Using Inventor manually
(C) 2021 Owen F Ransen
You can also get the above dialog by right clicking on the view andselecting "edit".
14.46 Creating a workplane offset from another plane
Here is how to move a workplane, offsetting a workplane, use thismenu:
476 Autodesk Inventor Programming in C++ by Owen Ransen
(C) 2021 Owen F Ransen
And this sequence to specify the offset:
14.47 Customizing the menu
Use the tools tab customize icon.
477Using Inventor manually
(C) 2021 Owen F Ransen
14.48 Delete a parameter
Use the Parameters list dialog box and right click on the line of theparameter you want to delete.
Note that if the parameter is in use you'll not get a "Delete Parameter"menu item.
14.49 Deleting, removing a constraint
Right click on the constraint in the browser and choose "delete".
The delete key on your keyboard will not work for this operation, itseems.
14.50 Driven Dimensions and their Removal/Change
Driven dimensions are controlled by the geometry.
Turning a driven dimension into a normal dimension: Right click onthe dimension then if it is a driven dimension a small window willshow you a check box checked. Uncheck it.
Driven dimensions have brackets around them, like: (45,921)
Compare these with driving dimensions.
14.51 Editing a sketch flatly
Use the look at command (rectangle and arrow icon) and click on thesketch to get that sketch flat on the screen.
14.52 Editing Model Parameters and how they are displayed
Double click on a dimension in a sketch to change the value of thatdimension.
To see the name of the dimension change the document settings asfollows:
478 Autodesk Inventor Programming in C++ by Owen Ransen
(C) 2021 Owen F Ransen
Select Display As Expression in the radio buttons. Then you'll get"d0=45" rather than just "45". Not only but you can also change thename of the parameter, for example from "d0" to "DiamTube".
14.53 Enable and Disable parts and assemblies
If you right click in the browser a part you can Enable or not Enable it.When not enabled it goes green and cannot be selected.
14.54 Example of dimensions and parameters in a sketch
Two circles, to form a tube, later. Change the names from d1 and d2then add a thickness:
480 Autodesk Inventor Programming in C++ by Owen Ransen
(C) 2021 Owen F Ransen
And you'll get a tiny dialog where you can type in a formula:
481Using Inventor manually
(C) 2021 Owen F Ransen
Click on the green tick. You'll see the driven dimension:
482 Autodesk Inventor Programming in C++ by Owen Ransen
(C) 2021 Owen F Ransen
14.55 Extruding sketches with multiple concentric circles
If you add several concentric circles into an Inventor sketch, whenyou extrude the sketch, Inventor will need to know which areas youwant to extrude. Click inside the ones you want.
483Using Inventor manually
(C) 2021 Owen F Ransen
Three circles have been interpreted correctly when the extrusionhappened.
14.56 Extruding with widening angles
When you are extruding something you can use the tab key to switchbetween length minibar and angle minibar.
484 Autodesk Inventor Programming in C++ by Owen Ransen
(C) 2021 Owen F Ransen
14.57 File types
Inventor Standard Part File: *.ipt.: Used for storing general single ormulti-body components or part. For example a shaft, bolt, etc. Partfiles are the building blocks of any design. Collections of part filescome together to make an assembly. The Inventor standard part filecan be created easily by using the Standard (mm).ipt, Standard (in).ipt or Standard.ipt template on the New File dialog box.
Inventor sheetmetal part file: *.ipt. Used for creating parts (andiParts?) or components with constant and thin thicknesses. Mostsheet metal parts have thicknesses ranging from 1 mm to 6 mm. Youcan create sheet metal parts by using the Sheetmetal (mm).ipt,sheetmetal (in).ipt or sheetmetal.ipt template on the New File dialogbox.
Standard Assembly File: *.iam. It is used for storing assembly files.Collections of part files come together to make an assembly. Anassembly file is made of parts or components that are linked to eachother parametrically. All assemblies without weldments areaccommodated here. Inventor standard assembly files can be createdby using the Standard(mm).iam, Standard(in).iam or Standard.iamtemplate on the New File dialog box.
Inventor Weldment Assembly File: *.iam. This type of assembly fileis used for creating assemblies that require welding process forjoining one part or component to another. This file type can becreated by using the Weldment.iam template on the New File dialogbox
Inventor Drawing File: *.idw or *.dwg. The Inventor detail drawingfiles are used for creating design documentation. In a drawing file,one creates views (sectioned, detailed, orthographic, auxiliary, etc)accompanied with annotations, dimensions and Bill of Materials (BOM). There are two ways of creating drawing files in Inventor. Oneis with the *.idw file type and the other is with the *.dwg. The DWGformat is an industry standard and such files may be viewed withAutoCAD-based applications.
Inventor Presentation File: *.ipn *.ipt: Used for creating exploded
485Using Inventor manually
(C) 2021 Owen F Ransen
views of assemblies. These exploded parts could be animation tovisualize how the parts will be assembled Can be created by usingthe Standard(mm).ipn, Standard(in).ipt or Standard.ipn.
Inventor Project File: *.ipj : This is like the root of a large project.
Inventor iFeature file: .ide : A file for an iFeature..
14.58 FlipNormal and WorkPlane constraints
When you use WorkPlanes for constraints remember that they have anormal direction. The normals are the white arrows in the diagrambelow:
You can change the normal direction by choosing FlipNormal from theworkplane's context menu.
486 Autodesk Inventor Programming in C++ by Owen Ransen
(C) 2021 Owen F Ransen
If you see a red(dish) workplane you are looking at the front of it.If you see a blue(ish) workplane when you are looking at the back ofit.
14.59 Flush Mate And Axis Constraint Example
To put a tube inside a hole inside another tube you can make a flushcostraint with a workplane tangential to the cylindrical surface:
And the next step is to make the two axes coincident:
487Using Inventor manually
(C) 2021 Owen F Ransen
So two constraints.
14.60 Free Move and Free Rotate
These commands (right click on a part inside an assembly) allow youto move and rotate the part freely. But it is only temporary, maybe toallow you to see something better.
The move or rotation is not saved when you save the assembly. Afree move is a temporary "get out of the way" move.
14.61 fx: and parameters and formulas
If you add a dimension but set it not to a numeric value but to aparameter, then that dimension will be shown with an fx: in front of it.
488 Autodesk Inventor Programming in C++ by Owen Ransen
(C) 2021 Owen F Ransen
To get a sketch dimension to be a user parameter all you need to dois1. Create the user parameter. Use the big f icon under the manage
tab.2. When you create an object in sketch mode, instead of typing in a
number, type in the name of the user parameter.
These are called driving dimensions. Compare them to drivendimensions.
Difference between model parameters and user parameters.Model Parameters are created automatically when you create anobject, and are given automatic names, d0 for the diameter of the firstcircle you draw, for example. You can name model parameters on thefly, for example when you draw a circle, and then do a dimension of itinstead of typing 35, type InnerTube=35 directly. In that way whatwould have been d4 (for example) becomes InnerTube. Actually typethat into the tiny dimension edit box. It will then appear in the f dialog.
User Parameters are created by you to maybe drive dimensions, andmaybe be applied to more than one part of the sketch.
14.62 Get the browser pane back
Go into the view tab and click on the user interface icon near thecenter.
14.63 Getting into and out of sketches
To get into a sketch, in the browser on the left of the screen right clickon the node called, for example, "Sketch1" and choose Edit Sketch.
To get out of a sketch simply click on the green Finish Sketch icon attop right of the main tool bar.
It pops up also if you do a right click anywhere on the sketch.
489Using Inventor manually
(C) 2021 Owen F Ransen
14.64 Getting to the constrain icon in Inventor
You must be in assembly mode to see the constrain icon!
Doh!
14.65 Grounded Parts
An assembly is a collection of parts and by default the firstcomponent in an assembly file will be grounded. This means it cannotmove, and probably the other components will be offset relative to it.This assembly has two parts. The pushpin says which is groundedand cannot be should not be moved.
Here is another visual example:
490 Autodesk Inventor Programming in C++ by Owen Ransen
(C) 2021 Owen F Ransen
14.66 Holes in tubes
If you want a hole in a tube at an arbitrary angle it best to base thehole on a sketch.
The sketch will have a point at 0,0 and you select "Placement fromsketch" from the hole dialog.
The sketch must move around with the angle. To do this you need asketch in the plane parallel to the base of the tube:
491Using Inventor manually
(C) 2021 Owen F Ransen
That bright hole is what you attach the smaller sketch to:
492 Autodesk Inventor Programming in C++ by Owen Ransen
(C) 2021 Owen F Ransen
If you use some other method it may be that not all angles around thetube are respected.
14.67 How to change the background of the Inventor screen
Use Tools | Application Options | Colors tab.
14.68 How to make a hollow tube
1. Start a new part, clicking in the main window.2. Make a new sketch for this part.3. In the 2d commands draw a circle.4. Select Offset and so make another circle inside the first.5. After getting the two circles to the rights size clikc on Finish sketch6. You are now in the 3d Model tab7. Click on Extrude and click between the two circles so that the ring
493Using Inventor manually
(C) 2021 Owen F Ransen
becomes grey.
14.69 How to move a 3D object
Simply right click in the browser on the object you wwant to move:
You will get 3 axes which you can drag.
494 Autodesk Inventor Programming in C++ by Owen Ransen
(C) 2021 Owen F Ransen
14.70 Inches problem
Sometimes you create a new project and unless you are careful thefirst part you put in will be in inches. When you create the componentbe sure to select the Metric/Standard (mm).ipt template. You mayhave to hit the browse button in the dialog to do that.
Alternatively in the Project dialog Folder Options you can point thetemplate directly at:
Templates = C:\Users\Public\Documents\Autodesk\Inventor 2013\Templates\Metric\
14.71 Insert constraint
The insert constraint has an axis and a plane to match to another axisand another plane. Or rather two circles which together identifyeverything neccessary to insert a countersunk screw into acountersunk hole.
14.72 Inserting an inclined workplane
Here are the steps.
Make sure an axis is visible, like that Inventor will give you thepossibility to rotate it later:
495Using Inventor manually
(C) 2021 Owen F Ransen
It may be the fact that you have selected an axis which allows you toincline the plane later. Which happens in the fourth step:
496 Autodesk Inventor Programming in C++ by Owen Ransen
(C) 2021 Owen F Ransen
14.73 Inventor Apprentice
Apprentice Server is basically a read-only subset of the Inventor APIunless you are doing some file manipulations - like savecopyas. It'snot a great subset either. I have not been able to use it much in myapps yet.
Inventor Apprentice is a freely available programming component thatcan be used by a program to read information from Inventor files. In afew cases, it is also possible to write information. A key part ofunderstanding how to use Apprentice is to understand what itscapabilities are, both what it can and cannot do. This class will look atthe functionality of Apprentice using several sample programs toillustrate its capabilities.
497Using Inventor manually
(C) 2021 Owen F Ransen
The simple way to think of Apprentice is that it's a smaller version ofAutodesk Inventor that does not have a user interface. Without a userinterface the only way to access its functionality is by using its API.Apprentice is actually an ActiveX component. It runs within theprocess space of the client that's using it. For example, if you write aVisual Basic program that displays information about the contents ofan assembly, Apprentice will be running within your VB program'sprocess space. Apprentice can be very efficient for certainapplications because it's smaller than the complete Autodesk Inventorapplication and because it runs in the same process as yourapplication.
The API exposed by Apprentice is a subset of the complete AutodeskInventor API. Apprentice provides access to file references, assemblystructure, B-Rep, geometry, attributes, render styles, and documentproperties. Access to the assembly structure, B-Rep, geometry, andrender styles is read-only.
14.74 Mate vs Flush constraints
498 Autodesk Inventor Programming in C++ by Owen Ransen
(C) 2021 Owen F Ransen
14.75 Mini tool bar autofade
Switch autofade on and off using the minitoolbar options, usually amenu near the red X button.
14.76 No visible unadaptive sketches
You might get this error message:
No visible unadaptive sketches
...if you make a sketch at assembly level rather than part level.
14.77 Pattern inside a sketch
You can make a pattern inside a sketch. Look at the red rectanglesbelow:
You need to create construction lines to specify the axes you need forthe rectangular pattern.
499Using Inventor manually
(C) 2021 Owen F Ransen
14.78 Patterns (arrays) of features
To create a rectangular array of features follow these steps whichshow how to create a linear array:
500 Autodesk Inventor Programming in C++ by Owen Ransen
(C) 2021 Owen F Ransen
1. Click on the rectangular pattern icon (the dialog pops up)2. Select the feature3. Click on direction icon4. Click on (for example) and axis5. Modify the spacing
And voila':
501Using Inventor manually
(C) 2021 Owen F Ransen
14.79 Plane on the surface of a tube at an angle
Create a sketch with a circle and a line. Add a point at theintersection of the circle and the line:
You may have to promote that sketch to see it at Part level.
Anyway, then use the WorkPlane at tangent to surface through point:
502 Autodesk Inventor Programming in C++ by Owen Ransen
(C) 2021 Owen F Ransen
14.80 Problem when inserting iParts into Assemblies
You may get one of these messages while trying to insert a specificmember of an iPart:
Problems encountered while saving the document.The filename, directory name, or volume label syntax is incorrect.The database in P:\...\Part1.ipt.* could not be saved
When it happened to me I found that only certain members hadproblems. I had to copy those members in the iPart Author with atemporary new member name, then delete the offending rows, thenrename the member to the original code.
For example code (member) 123456 gives you problems:
503Using Inventor manually
(C) 2021 Owen F Ransen
1. Create a new entry in the table, 123456N for example.2. Set the column values to be the same as 123456.3. Delete 123456, and rename 123456N into 123456. You'll be
warned that changing the member name will change the filename.Continue anyway.
14.81 Problems encountered while executing this command.
You may get this message if you are trying to do something in anAssembly when you should be doing it in a Part.
For example you will not be able to extrude from a sketch in anAssembly, but you will inside a part.
14.82 Problems with sketch extrusion and revsurf
There are many things which can go wrong. Remember to use thebutton for drawing construction geometry and for changing sketchgeometry to construction geometry:
I've found it easier not to use projected features, base your sketch onvariables and dimensions.
14.83 Project files
You should start all new projects with a project file, it'll have theextension .ipj.
Projects are a way of organizing many components, parts,
504 Autodesk Inventor Programming in C++ by Owen Ransen
(C) 2021 Owen F Ransen
assemblies etc. There are two main reasons for having a project file.
1. Organise a single standalone project2. Have a library of read only components.
For single users project directories contain all the (new) componentsof the project, i.e. sub drectories are not used. Libraries contain partsand assemblies which will not be modified.
The book: Mastering AutoDesk Inventor 2013 has some interestingtechniques for project files.
Project files are XML files. Note that when you open a .ipt or .iam thedialog box also specified the project:
You can set the top level directory of all your projects using the Application Options dialog.
Include= (in the project options dialog) tells you which other projectscan be accessed from this project.
505Using Inventor manually
(C) 2021 Owen F Ransen
14.84 Putting 2d dxf files in 3D assemblies, manually
You may want to put a 2D dxf file in a 3D position in an assembly:
To do this you must create a plane in the plane you want to DXF fileto appear, then add a sketch to that plane. Then, from AutoCAD copy(COPYCLIP) the entities of the DXF file and paste them into thesketch.
Precise locating has been beyond me so far, and even if the entitypasted is a block it gets changed into component lines and circles.
14.85 Removing material with the cut extrusion command
Here is the sequence:
506 Autodesk Inventor Programming in C++ by Owen Ransen
(C) 2021 Owen F Ransen
14.86 HealthStatusEnum
Here are two health status values which I've currently found:
kCannotComputeHealth 11783 Object cannot be evaluated.
kUpToDateHealth 11778 Object is up to date.
Here's a fragment of how it can be used, in this case with a RectangularPatternFeature...
const HealthStatusEnum eHealth = pRectPatFeature->GetHealthStatus(); gLogger.Printf(ekLogMsg, L"For pattern <%s> eHealth = %d",kcsPatternName, eHealth); if (eHealth == kCannotComputeHealth) { gLogger.Printf (ekErrMsg,L"Pattern health is bad %s\n",kcsPatternName) ; return E_FAIL ; }
507Using Inventor manually
(C) 2021 Owen F Ransen
There are a lot of values for HealthStatusEnum, and I'm not sure ofthe meaning of all of them.
14.87 Showing dimensions temporarily
In the browser right click the object (for example a feature) and select Show Dimensions. Select the same object to switch them off.
To remove the dimensions just click somewhere else in the browser.I'm not totally clear on all this at the moment.
14.88 Showing expressions in a sketch
In the sketch right click on the graphics screen and select
Dimension Display - > Expression
14.89 Sketch plane
The sketching plane is by default the XY plane and extrusions goalong the Z axis.
But you can change the default sketch plane, use the Tools tab,application options dialog, Part tab.
14.90 Sketches and Features
In general Sketches are 2D and features are 3D objects.
You have a basic solid feature created from a 2D sketch.
509Using Inventor manually
(C) 2021 Owen F Ransen
14.91 Suppression and mirrored features
If you suppress a part, will its mirror be suppressed too? Butremember that suppression of parts is only for LOD applications,Level of detail.
Yes.
14.92 Templates and Template files
You will find the template files in this directory (or something similar)
C:\Users\Public\Documents\Autodesk\Inventor 2013\Templates
When you create a new file (a new assembly or part) the templatechoosing dialog...
510 Autodesk Inventor Programming in C++ by Owen Ransen
(C) 2021 Owen F Ransen
...will respect what is inside the templates directory...
511Using Inventor manually
(C) 2021 Owen F Ransen
14.93 The Marking Menu
This is the menu which pops up when you right click in the graphicsarea.
You can use that to get to know where some commands are, so thatyou can use mouse gestures (drag with "other" button pressed) forvery quick access.
512 Autodesk Inventor Programming in C++ by Owen Ransen
(C) 2021 Owen F Ransen
14.94 Trim and Fillet
Fillet and Chamfer:
These commands exist in Inventor in the sketch tab. Select two lines(use the shift key for multiple selection) then click on the Fillet (orChamfer only one will be visible at the same time) icon in the toolbar.You can change the radius of the fillet by clicking on the numberwhich specifies the current size.
Chamfers also have a size and again you change change it by doubleclicking on the number.
Trim:
513Using Inventor manually
(C) 2021 Owen F Ransen
In Inventor trimming is easy Create a sketch with two overlappingrectangles, click on the Trim command (middle of the toolbar) andhover the mouse over the lines which intersect. Click to actually trim.
These are sometimes called placed features and should be done atthe end of a job, not at the beginning.
14.95 ul as a dimension
ul means unitless and you'll see it inside rectangular patternproperties as a count of the number of repititions.
14.96 Units, Inches, Mm
If you find yourself suddenly working in inches for some reason usethe Tools -> Application Settings dialog, -> Files tab -> ConfigureDefault Template.
Set it to ISO and mm.
14.97 Vault
Autodesk Vault locks down Inventor files for their protection.
There is a Vault icon in the Inventor toolbar.
14.98 View face command
The view face command lets you select a face in a 3D object andview it head on, from its normal type like.
14.99 Viewing Multiple Documents in Inventor
If you have more than one document or window open in Inventoryou'll see it in the tabs, as shown below:
514 Autodesk Inventor Programming in C++ by Owen Ransen
(C) 2021 Owen F Ransen
14.100Work Axis Thru Circular Hole
Do it like this:
Simples! No?
515Using Inventor manually
(C) 2021 Owen F Ransen
14.101Work Point in center of a hole (COPY)
The insert constraint requires a flat object, and a tube in a cylinder isnot a flat circle
So this will not give you an insert constraint...
...which is why they've added a point in the center of a loop of edges.
14.102Workplanes and Sketches, Creating a sketch on an arbitraryplane
Workplanes need geometry, for example 3 points. Often workplanesare added to parts.
First you make a workplane, so far what I have done is insert 3 pointsand use the workplane from 3 points command. Then make a sketchform that.
Default workplanes exist in every part, xy yz and xz planes.
516 Autodesk Inventor Programming in C++ by Owen Ransen
(C) 2021 Owen F Ransen
FYI in a program workplanes can be accessed like this:
517Using Inventor manually
(C) 2021 Owen F Ransen
14.103WorkPoint in center of a hole
If you want to place a work point in the center of a hole one option isto use the "Point In Center Of Loop Of Edges" function:
You'll have to select one of the two circles which forms the hole.
Autodesk forum also showed me this:
518 Autodesk Inventor Programming in C++ by Owen Ransen
(C) 2021 Owen F Ransen
See also center points and non.
14.104Yellow Dot Green Dot Constraints
When doing a sketch yellow snap nodes are not constraints, whereasgreen snap nodes are constraints.
A circle with a center snapped off the origin (becomes a yellow node),maybe on a axis, can be moved. These are called "soft snaps".
A circle with a center snapped on the origin (becomes a green node),cannot be moved. Snapped to green are called "hard snaps" becausethe object cannot be moved afterwards.
15 Acknowledgements
Thanks to, in alphabetical order (many, but not all, of these peoplework for AutoDesk):
519Acknowledgements
(C) 2021 Owen F Ransen
Vladimir AnanyevBrian Bolam
Carlos Manuel Carreiras Jonathan D. Kriek
Dave Hoder Bob Holland
Philippe LeefsmaXiaodong Liang
Adam NagyHerm Jan Otterman
Kean WalmsleyCaroline Ward
Chandra Shekar G Johnson Shiue
If I've left anybody out, my apologies and please let me know!
Autodesk Inventor Programming in C++ by Owen Ransen520
(C) 2021 Owen F Ransen
Index
- " -"Center Point" getting hold of it programatically 112
"ul" unitless parameters 103
- . -.addin 18, 263
.AddIn file directory 263
.AddIn file in Autodesk Inventor C++ Programming 257
.AddIn manager 281
.addins directory 302
.DEF file 281
.dwg 474
.dwg file types 484
.EXE file 18
.Expression vs .Value 358
.iam file types 484
.ide file types 484
.idw 474
.idw file types 484
.ipj 503
.ipj file types 484
.ipj programatically 278
.ipn file types 484
.ipt file types 484
.rgs file for Inventor AddIns, what is it? 272
.tlb 282
.tli 282
.Value vs .Expression 358
- : -::SysFreeString 272
- [ -[item] in C# lists 376
- \ -\n in a table 146
\r in a table 146
- _ -_b_str filename 106
_bstr_to CString 272
_com_error (Autodesk Inventor) 158
_T macro 272
_WIN32_WINNT=0x0501 in Inventor Programming 73
- 0 -0x80004005 AddByPlaneAndOffset not suppored inassemblies 295
0x800401e3 MK_E_UNAVAILABLE AutodeskInventor Programming 74
0x800401f3 CLSIDFromProgID failure 76
- 1 -1083 282
1083 in Inventor Programming 75
11778 Object is up to date health of pattern 506
11783 Object cannot be evaluated health of pattern 506
12291 134
- 2 -2064: term does not evaluate to a function taking 0arguments 77
2130706443 134
- - --2147467259 registration error in InventorProgramming 78
- 2 -2774 compile error in Inventor programming 77
2d and 3d points (abstract geomety) 183
Index 521
(C) 2021 Owen F Ransen
2d dxf files in 3D assemblies 505
2d points in a sketch, listing their coordinates 97
2d sketch 477
2d sketch solid feature 507
- 3 -3073 error 302
32 vs 64 in Autodesk Inventor Programming in C 302
3277: Found conflicts between different versions 326
3D snap spacing 458
- 4 -4278 Autodesk Inventor Programming 78
- 5 -50348544 is kModelParameterObject 134
- 6 -64 bit AddIn in Autodesk Inventor Programming inC++ 290
64bit vs 32bit in Autodesk Inventor Programming inC++ 290
67113776 134
- 8 -80004005 AddByPlaneAndOffset not suppored inassemblies 295
80004005 CreateGeometryProxy 162
80004005 error when saving Inventor documents 209
800401f3 CLSIDFromProgID failure 76
80070057 and WorkFeature visibility 188
83886592 134
83887616 134
83893504 134
83893664 134
83923968 134
- A -Access and connecting to Inventor 43
Acknowledgements 518
Activate function in plugin 342
active document 278
Active Document, Inventor programming in C++ 255
Active Inventor Document, how to get it 289
active project files programatically 307
ActiveDocument 156
Adaptive geometry 60
Add a circle to a sketch function 81
Add a column into an iPart table 425
Add a DrawingSketch to a DrawingDocument 89
Add a DrawingSketch to an IDW 90
Add a feature to an existing pattern 449
Add a line by two points 90
Add a mate constraint with two planesprogramatically, Autodesk Inventor Programming 160
Add a part to an assembly function 66
Add a part to an assembly programatically 291
Add a plane by offset from another plane 295
Add a point to the surface of a tube manually 450
add a rectangle to a sketch programatically 284
add a rule as a button in iLogic 40
add a sheet to a drawing 71
Add a sketch based on a workplane 195
Add a sketch offset from a plane 295
Add a sketch on a part's default workplaneprogramatically 265
add a sketch programatically 247
Add a sketch to an assembly or part 61
Add a unitless user parameter into an assembly 103
Add a work point at a sketch point 268
Add a workplane based on an existing workplane 195
add a workplane in an assembly programatically(AddFixed) 445
add a workplane programtically 251
Add a WorkPoint at the intersection of a line and aplane 113
Add a WorkPoint into an assembly manually 112
Add a WorkPoint into an assembly programatically 112
Autodesk Inventor Programming in C++ by Owen Ransen522
(C) 2021 Owen F Ransen
Add an angular dimension 451
Add an assembly into another assembly,programatically 101
add an extrusion to a part programatically 242
Add an iMate (based on a point) into an assembly 97
Add an occurrence of a part to an assembly 66
Add an occurrence to an assembly does not work 201
add assembly in anpther assembly, programatically 101
Add Form and iLogic 40
Add function calling (occurrences) 201
Add grounded WorkAxis in an assemblyprogramatically 114
add in C# member not found 353
Add in the occurrence of a custom iPart into anassembly 214
Add lines to a DrawingSketch 90
add named sketch to named workplaneprogramatically 247
add part to an assembly 66
add parts using iLogic 33
add rectangle to sketch 108
Add text to an Inventor document 450
Add to New Folder 436
Add views to an IDW 149
Add vs MethodAdd 224
AddAsTwoPointRectangle 284
AddBaseView 149
AddBrowserFolder 83
AddByCenterRadius 81
AddByCenterRadius example 242
AddByPlaneAndOffset 251
AddByPlaneAndOffset example 196
AddByPlaneAndOffset not suppored in assemblies 295
AddCircleToSketch 81
AddCustomiPartMember tips and hints and help 213
AddCustomiPartMember, how to use it in C++ 214
AddFixed 112
AddFixed axis in assembly based on a hole in a part 374
AddFlushConstraint 260
AddFlushConstraint in Autodesk Inventor C++Programming 258
AddFlushConstraintOfTwoPlanes with max distance 49
AddForSolid and profiles and AutoDesk InventorProgramming in C++ 274
AddForSolid example 242
AddGround and sketch origin 92
Add-In automatic load suppression 453
addin dll 263
AddIn file 257
addin loading 263
AddIn Manager 281
AddIn, Autodesk Inventor Programming in C++ 18
addin, C# 328
adding a button C# 338
Adding a Dimension in a sketch 452
Adding a flat parts list in a drawing 402
Adding an AngleConstraint 302
Addins in C# 347
AddiPartMember 206
AddiPartMember and rotation 185
AddLineByTwoPoints in a sketch 90
AddMateConstraint 160
AddMateConstraint2 at assembly level 385
AddMateConstraintOfTwoPlanes 160
AddMateiMateDefinition example 97
AddSketchToStdWorkplane 265
AddSketchToWorkplane Autodesk InventorProgramming in C++ 247
AddTwoPointDistance explanation 92
adequate constraint in sketch 459
administrator for regsvr32 in Inventor Programming 74
AffectedOccurrences in an extrusion 109
All occurrences are oriented identically. 271
All occurrences fitted within path length. 271
All occurrences fitted within specified distance. 271
Alternative to a virtual component in a BOM 413
Ananyev 518
angle (Inventor Programming) 173
angle, adding an angle constraint 302
AngleConstraint programatically 302
angular constraing programatically 302
angular constraints 400
angular dimension, how to add manually 451
angular units and Autodesk Inventor Programming 173
application invisible 185
Index 523
(C) 2021 Owen F Ransen
application options 507
Application Options Settings 452
application visible 185
Apprentice Server 496
array of double values as an array for Inventor 147
array of features 499
arrays (rectangular) in Autodesk InventorProgramming in C++ 233
Arrays in COM 96
Ascii 22
ASCIIand UNICODE 272
Assemblies - Hierarchy 290
assembly .iam file types 484
Assembly Close programatically 155
Assembly creation programatically 275
assembly document creation 291
assembly document opening (Inventor API) 68
assembly file types 484
Assembly in .AddIn file 257
assembly inside assembly, programatically 101
Assembly level workaxes 429
Assembly vs Part for work things 440
assembly workaxis and constraints 385
assembly workplanes, constrain to C# 379
Assembly WorkPoints and Part WorkPoints 440
Assembly WorkThings vs Part WorkThings 440
Assembly.Document get current one 289
AssemblyComponentDefinition 216
AssemblyComponentDefinition - Hierarchy 290
AssemblyComponentDefinition and componentoccurrences 198
AssemblyComponentDefinition C# 345
AssemblyComponentDefinition is a list of parts andconstraints 249
AssemblyDocument creation in C# 389
AssemblyDocument from general Document 291
AssemblyDocument or PartDocument C# 355
AssemblyDocument, get currenr document 289
Asset is null 47
asset lib access programatically 47, 52
asset looping 47, 52
asset purging in part documents 303
Asset Type 52
assets, material API 52
Attribute Sets in Inventor Programming 238
Attributes in Inventor programming in AutodeskInventor Programming in C++ 238
author of iParts 417
Autodesk Inventor COM API 22
AutoDesk Inventor functions 244
Autodesk Inventor Programming in C++ basicarchitecture of the source code 18
Autodesk Inventor Programming in C++ how to usethis book 17
Autodesk Inventor Programming Pattern Elements 190
Autodesk Inventor programming, COM and SmartPointers 22
Autodesk inventor version programatically in C++ 138
Autodesk.iLogic.Automation reference 347
Autodesk.Inventor.Interop version problems 326
autofade on and off 498
Axes (standard X Y Z( 170
Axis (X Y Z standard) 170
Axis And Flush Mate Constraint Example 486
axis constraint offset parameter 461
axis constraint parameter 461
axis constraint radius parameter 461
axis constraints 461, 486
axis direction 435
axis of a hole C# 374
Axis perpendicular to sketch point, how to 442
Axis Thru Circular Hole 514
- B -background of Inventor screen options 492
Backup files 452
Backup options for Inventor files 452
Base View 474
BaseView 149
BBox of a part in C# 380
BBox of a part occurrence in an assembly 49
BBox of a parts list 103
bias and point offset 426
biaspoint and point offset 426
Bill of materials 402
blue objects in a sketch 463
Bolam 518
BOM 402
BOM and substitution 404
BOM put_Reference 85
BOM quantity programatically 87
Autodesk Inventor Programming in C++ by Owen Ransen524
(C) 2021 Owen F Ransen
BOM row programatically 85
BOM Static part counts and quantities 413
BOM Static quantity in a programatically 87
BOM view parts only 405
BOM view type row programatically 85
BOM vs Parts List 401
BOM with virtual components 406
BOMRow 85
BOMRowsEnumerator 85
BOMViewTypeEnum 85
boolean values in COM 229
boolean VARIANT_BOOL 229
Bounding box of a part C# 380
Bounding box of a part occurrence in an assembly 49
bounding box of a parts list 103
Box2d and get_RangeBox 103
BoxPtr of a part in an assembly 49
Browser visibility 455
browser folder 436
Browser folder name getting 84
Browser is missing! Get it back! 455
browser pain on and off 488
Browser panes in C# 355
Browser, Folder, Pane programatically 83
Browset folders, looping over them 84
BSpline Surface 300
BSTR and ::SysFreeString 272
BSTR from CString 307
BSTR OLECHAR wchar_t 272
BSTR vs CComBSTR 272
button definition C# 338
button in C# 338
button, ribbon, tab C# 332
buttons and iLogic 40
buttons and rules in iLogic 40
Byname, items in lists C# 376
- C -C# 275
C# addin 328
C# and parameters 358
C# AssemblyComponentDefinition 345
C# calling iLogic 347
C# ComponentOccurrences 345
C# GUI adding a button 332
C# iLogic listing of the rules 351
C# Inventor references 322
C# Looping over components inside an assembly in 345
C# message box 342
C# NameValueMap 344
C# Open an Inventor file using 344
C# plugin making 328
C# plugins, adding a button and a command 332
C# running Inventor 322
C# TransientObjects 344
C++ 275
C++ from VBA 244
C1083 in Inventor Programming 75
C1083: Cannot open type library file: 'RxInventor.tlb':No such file or directory 282
C1189 error in Inventor Programming 73
C2064: term does not evaluate to a function taking 0arguments 77
C2774 compile error in Inventor programming 77
C4278 Autodesk Inventor Programming 78
Calling iLogic from C# 347
Camera and zoom 46
cannot add feature to existing pattern 449
Carreiras 518
carriage return inside table cells 146
cast from AssemblyDocument to Document 318
cast from Document to Part or Assembly 355
cast IDispatch** and get_Document 95
cast to get part document 156
cast to IDispatch**, in Autodesk InventorProgramming 195
Casting from a ComponentDefinition to aPartComponentDefinition. 205
casting using CComQIPtr example 51
category of material 47, 52
CComBSTR and wchar_t in the Autodesk InventorAPI 208
CComBSTR cast in Add function call 201
CComBSTR in AutoDesk Inventor Programming 201
CComBSTR vs BSTR in Inventor programming 272
CComPtr and how to release them in Inventorprogramming 225
CComPtr constructor 183
CComPtr is initialised to nullptr automatically 183
Index 525
(C) 2021 Owen F Ransen
CComPtr release memory by setting it to nullptr. 225
CComPtr vs CComQIPtr 287
CComPtr<Parameter> 230
CComPtr<Point> Autodesk Inventor Programming 183
CComPtr<Point2d> Autodesk Inventor Programming 183
CComQIPtr and QueryInterface 139
CComQIPtr and Release 140
CComQIPtr example of casting 51
CComQIPtr is better than QueryInterface 140
CComQIPtr vs CComPtr and AutoDesk InventorProgramming in C++ 287
CComStr and programming Autodesk's Inventor 272
CComVariant and VARIANT 287
CComVariant gkvarEmpty 97
cells in tables in IDW drawings 143
center point for hole 467
Center Point, getting hold of it programatically 112
CenterPoints and Points 245
centimeters C# 389
Chamfer 512
change a model or user parameter programatically 57
change dimensions in sketches using iLogic 33
change dimensions in sketches using VBA 33
change document filename when saving Inventordocuments 209
change filename of object in the Autodesk InventorAPI 209
Change material / color of a solid 455
change name of a sketch 120
change name of workplane programatically 251
change parameter name 477
change parameters in sketches using iLogic 33
change parameters in sketches using VBA 33
Change size of a hole 51
change the default units 458
Change the offset elevation of a plane 456
Changing from iPart back to normal part 424
Changing home view setting 457
Changing manipulator snap 458
Changing parameters with C# 358
Changing the application visibility in AutodeskInventor Programming 185
changing the name of a drivng dimension 452
circle, add to a sketch 81
Circle2d and ProfilePath and CutFeature C# 363
Circular Hole With Work Axis 514
ClassId in the .AddIn file 257
clear all overrides 454
Client Graphics and AutoDesk Inventor Programmingin C++ 290
ClientId in the .AddIn file 257
CLogger 313
Close (SkipSave) Inventor API 211
close a sketch edit with ExitEdit 90
Close and SaveAs Autodesk Inventor API C++ 211
Close function, Inventor API 211
Close of a part programatically 155
Close of an assembly programatically 155
Close with SkipSave 155
CLSIDFromProgID failure 76
CLSIDFromProgID for Excel 312
CLSIDFromProgID for Inventor 312
CLSIDFromProgID in Autodesk InventorProgramming in C++ 291
cm inches (Inventor Programming) 173
cm or mm in C# units 389
cm parameters 235
CoCreateInstance for Inventor 312
CoInitialize and AutoDesk Inventor Programming inC++ 172
COleSafeArray VARIANT arrays of strings 214
collections, getting items from them 288
color and material of a solid 455
colors of Inventor screen options 492
Column Chooser in a parts list 413
column substitution in BOMs and parts lists 404
ColumnCount is strange 194
COM and AutoDesk Inventor Programming 172
COM API and pointers and memory in AutodeskInventor Programming in C++ 225
COM arrays 96
COM DLL registering 281
Com error 80070057 188
COM errors in Autodesk Inventor 158
COM errors, and Autodesk Inventor Programming 166
COM Function calls in Autodesk Inventor C++programming 224
COM macros in Inventor C++ programming 158
COM ParameterPtr 230
Autodesk Inventor Programming in C++ by Owen Ransen526
(C) 2021 Owen F Ransen
COM points matrices vectors Autodesk InventorProgramming 183
COM return values 166
COM RxInventor 282
ComBSTR from CString 307
compiling with MFC dialog (for Autodesk Inventor) 78
complete constraint in sketch 459
Completely and adequately constrained sketches 459
component definition and occurrences 216
component definition of newly created assembly 291
Component definition, definition of, InventorProgramming in C++ 249
ComponentDefinition from an Occurrence 205
ComponentDefinition from Doc 249
ComponentOccurence - Hierarchy 290
ComponentOccurence and ReferencedFileDescriptor 198
ComponentOccurence crash 223
ComponentOccurence mssing component 223
ComponentOccurencesList - Hierarchy 290
ComponentOccurrenceByName 198
ComponentOccurrences when creating an assembly 275
ComponentOccurrences in C# 345
Compute and Suppress from an iPart tableprogramatically 223
Compute or Suppress in iPart tables 424
ComVariant, CComVariant 287
concentric circle extrusion 482
Cone Surface 300
Connecting to Inventor form your C++ Windowsprogram 312
ConnectToInventor with C# 322
ConnectToInventor, running Inventor programatically, Autodesk Inventor Programming in C++ 22
Consistent Materials 52
Constrain 2 pairs of axes 461
Constrain a part to an assembly level work axis 385
Constrain a sketch point to a coordinate 92
constrain command 465
Constrain icon in Inventor 489
Constrain vertically and horizontally in a sketch 463
Constrain work axes C# 377
Constrain work things of a part to the work things ofthe containing assembly C# 379
constraint (flush) in Autodesk Inventor C++Programming 258
constraint (Insert) does not work 515
Constraint deletion 477
constraint error GetWorkPlaneNameGetOccurrenceName 46
constraint example (Inventor programming) 287
Constraint removal 477
Constraint, EntityOne, EntityTwo 201
constraint, parallel but nor coplanar 400
constraint, programming 160
Constraints - Hierarchy in Autodesk InventorProgramming in C++ 290
Constraints and parts from a programmer's point ofview 262
constraints and proxies 201
constraints and proxies (planes) Autodesk InventorProgramming 160
constraints between parts in an assembly 207
constraints in an asselmbly, listing them 169
constraints in sketches 459
constraints, angular 400
constraints, WorkPlane and FlipNormal 485
construction geometry 503
Construction lines in sketches 437
construction plane 251
contact set 465
contacts for Inventor Programming in C++ 15
contacts for Programming Inventor in C++ 15
convert from a CString to a BSTR. 307
convert from Document to AssemblyDocument 291
convert from general to drawing document 148
convert from IDispatchPtr to something else, ifpossible 137
convert generic document to partdocument 265
convert iPart into normal part 424
coordinate system right hand or left hand 27
coordinates of 2d points in a sketch, SketchPoint 97
Coordinates of a WorkAxis 294
CopyFile warning, Autodesk Inventor Programming 78
CoUninitialize and AutoDesk Inventor Programmingin C++ 172
CoUninitialize() and COM pointers 225
Count error C2064 77
Index 527
(C) 2021 Owen F Ransen
Counting the number of documents open in Inventor 141
crash when inserting a drawing 466
create a 2d point 108
create a 2d point (transient geometry) 183
Create a 3d point 112
Create a 3d vector 183
create a drawing from a part or assembly 474
create a geometric object 114
create a hole extruding 178
create a Line 114
Create a matrix 174
create a new document 275
create a new part 177
create a Point 114
Create a proxy geometry from an occurrence and aworkplane 195
Create a rectangular pattern of parts programatically 309
Create a sketch by default on creating a new part 467
create a sketch programatically example 22
create a virtual component manually 406
Create an assembly and add a part to it 291
Create an assembly document C# 389
Create an ObjectCollection of parts in an assembly 104
Create assembly 291
Create Extruded Feature: problems encounteredwhile executing this command. 503
Create iPart 416, 417
Create iPart icon is disabled 426
Create iPart icon is grey 426
create new assembly document 291
CreateDoubleVariantArray, Autodesk Inventor C++COM API 147
CreateExtrudeDefinition 242
CreateExtrudeDefinition and AddForSolid 274
CreateExtrudeDefinition example 242
CreateGeometryProcy, how to use it 162
CreateGeometryProxy 80004005 162
CreateGeometryProxy C# 374
CreateGeometryProxy crash 162
CreateMatrix 291
CreateNewPartDoc Autodesk Inventor Programming 177
CreateObject("Inventor.Application") 43
CreateObjectCollection in the Inventor API 176
CreateOneDim VARIANT arrays of strings 214
CreatePoint in Autodesk Inventor Programming 183
CreatePoint2d 284
CreatePoint2D in Autodesk Inventor Programming 183
CreateSafeDoubleArray 96
CreateSafeDoubleArray example use 132
CreateSafeStringArray 96
CreateSketchOffsetFromXYPlaneInAsm 295
Creating a big tube with holes in it 467
Creating a new Part Document Autodesk InventorProgramming 177
Creating a workplane offset from another plane 475
Creating an Assembly programatically 275
Creating folders in the browser programatically 83
Creating projected views from base views using theInventor API 153
CSafeArray 96
CSafeArray and IDW and CustomTable 143
CSLID and AutoDesk Inventor Programming in C++ 291
CString 22
CString and ComBSTR 307
CString from CComBSTR 272
CString to _bstr_t 272
CString to BSTR conversion 307
current active project programatically 307
current display driver stops responding errormessage 466
Curve2dTypeEnum.kLineSegmentCurve2d C# profileof sheet metal 392
Custom column in an iPart table 425
custom iPart 417
custom ipart programatically 214
custom iParts programatically 213
Custom iParts, changing parameters 422
Custom iParts, how to make and use them 419
Custom iProperties using C# 343
custom iProperties VBA 44
custom iproperty create and update with VBA andiLogic 38
custom Level of Detail (LoD) 28
custom propery reading 321
custom table, multiple lines in cells 146
customize the menu 476
Autodesk Inventor Programming in C++ by Owen Ransen528
(C) 2021 Owen F Ransen
CustomTables in Sheets and Drawings 143
cut extrusion 505
CutFeature and ProfilePath C# 363
cuts in a face of folded metal C# 363
cutting objects using an extrusion, programatically 109
Cylinder Surface 300
- D -database blah blah .ipt could not be saved 502
DebugView and iLogic 31
Declaring variables in iLogic 39
DEF file 281
Default Parameter Input Display 477
default project templates 494
default projects folder 452
default sketch 467
default sketch plane 467
default template 513
default units (mm or inch) 458
default variant 287
default workplanes 515
Default workplanes and sketches programatically 265
Default.ivb VBA 35
DeferUpdates 344
Definition from an Occurrence 205
Definition from Doc 249
degrees and radians and Autodesk InventorProgramming 173
degrees and radians SetToRotation 185
Delete a dimension manually 445
Delete a feature in a part 106
delete a parameter 477
delete a plugin 341
delete a workaxis programatically 295
delete pattern elements 441
Delete something from a Parts List 404
delete suppressed compoents with iLogic 31
DeleteFile warning, Autodesk Inventor Programming 78
Deleting a constraint 477
Derived parts C# 397
DerivedPartComponent C# 397
Description in .AddIn file 281
Description in the .AddIn file 257
descriptions of objects 134
DesignProject 307
DesignProjectManager 307
DestroyInventorGlobals, 20
detail drawing file types 484
DeveloperTools.Msi 15
dialog, adding one to iLogic 40
Dialogs in iLofic 40
diameter as a driven dimension 478
diameter of hole changing 51
diameter parameter 459
Difference between CComPtr and CComQIPtr? 287
Difference between model parameters and userparameters 487
DIID_PartDocument 156
dimenions, who to delete them manually 445
dimension editing 477
dimension in a sketch 452
dimension ModelValue 126
dimension name getting 137
dimension selection to show programatically 128
dimension types 137
DimensionConstraint 140
dimensions as user parameters 487
dimensions in a drawing sheet 131
dimensions needed. 459
dimensions, dirven 477
Dimensions, Retrievable 120
Dimensions, Showing temporarily 507
DimensionText 126
direction of a work axis programatically 294
direction of a workaxis 435
Direction of a workaxis programatically 373
directory for tlb files 282
Disable and Enable parts and assemblies 478
disabled iPart 426
disabled Parts Only problem 405
disabling user save 170
DISP_E_MEMBERNOTFOUND C# crash 361
displaying expressions in a sketch 507
DisplayName 281
DisplayName and full file name of the part 106
DisplayName in Autodesk Inventor C++ Programming 255
DisplayName in the .AddIn file 257
Index 529
(C) 2021 Owen F Ransen
DisplayName of occurrences 46
DisplayName vs InternalName 81
DisplayName vs Name 52
DisplayName vs PartName 45
dll addin 263
DllCanUnloadNow 281
DllRegisterServer 281
DllUnregisterServer. 281
Document from a Definition 95
Document getting 156, 255
Document iProperties (te 316
document name getting and setting 255
Document opening in Autodesk InventorProgramming in C++ 224
document settings 452
document type in VBA 37
document types 156
document types in Inventor 155
DocumentDescriptor, referenced document 118
Documents in VBA 36
Documents opening 224
documents programatically 224
Documents referenced by a 2d view in an IDW 88
DocumentType 156
DocumentTypeEnum 246
DocumentTypeEnum.kAssemblyDocumentObjectVBA 37
dotted lines in sketches, construction 437
double array, as a VARIANT 147
double parameters (ParameterTypeEnum) 235
double variant 287
drawing dimensions 128
drawing object 156
drawing object, create a new one 148
drawing of assembly 474
drawing of part 474
drawing page sheet size 71
drawing sheet addition 71
drawing view styles 154
DrawingDimension 126
DrawingDimensions 131
DrawingDocument and DrawingSketch 89
DrawingDocument creation 148
drawings, views, sheets, Inventor C++ API 149
DrawingSheetSizeEnum 71
DrawingSketch creation and manipulation 90
DrawingSketch to a DrawingDocument 89
DrawingView and projected views 153
DrawingView names 152
DrawingView, referenced documents 88
DrawingViews and dimensions 120
DrawingViewStyleEnum 154
DrawingViewStyleEnum , Inventor API 149
DrawingViewStyleEnum AddBaseView 149
driven dimension diameter example 478
driven dimension removal 477
driven dimensions, what are they? 477
driving dimensions 487
dwg 474
dwg file types 484
dwg object 156
DWG, create a new one 148
dxf files in 3D assemblies 505
- E -E_ABORT Operation aborted (Autodesk Inventor) 158
E_ACCESSDENIED (Autodesk Inventor) 158
E_FAIL Unspecified error (Autodesk Inventor) 158
E_FAIL COM macro and Autodesk InventorProgramming 158
E_HANDLE invalid handle (Autodesk Inventor) 158
E_INVALIDARG (Autodesk Inventor) 158
E_NOINTERFACE (Autodesk Inventor) 158
E_NOTIMPL (Autodesk Inventor) 158
E_OUTOFMEMORY (Autodesk Inventor) 158
E_POINTER invalid pointer (Autodesk Inventor) 158
E_UNEXPECTED (Autodesk Inventor) 158
Each quantity in a BOM 413
EdgeProxy and occurrence 236
Edit a sketch 90
Edit an iLogic function 27
edit sketch 488
edit the offset of a workplane 456
Editing a sketch flatly 477
editing dimensions 477
Editing Model Parameters and how they aredisplayed 477
email address for Inventor Programming in C++ 15
email address for Programming Inventor in C++ 15
Embed Interop Types C# compiling Inventor 361
Autodesk Inventor Programming in C++ by Owen Ransen530
(C) 2021 Owen F Ransen
empty variant 97, 287
Enable and Disable parts and assemblies 478
enable contact set 465
enabling user save 170
EntityOne and EntityTwo in a constraint 201
enum in GetTemplateFile 246
enum values and rxinventor.tlh 134
enum values of ObjectTypeEnum 134
enumerator for sheet sizes, DrawingSheetSizeEnum 71
enumerators for extrusion 178
Erase a feature in a part 106
erase a parameter 477
erase a workaxis programatically 295
Erase pattern elements 441
Erase something from a Parts List 404
Error 3277: Found conflicts between differentversions 326
error 80004005 when saving Inventor documents 209
Error C1083 in Inventor Programming 75
error C2064: term does not evaluate to a functiontaking 0 arguments, Autodesk Inventor Programming 77
error MSB3075: The command "regsvr32 /s /c inInventor Programming 74
error strings and codes from COM in AutodeskInventor 158
error when compiling in Autodesk InventorProgramming 73, 74, 75, 77, 78
ErrorManager for Autodesk Inventor Programming 166
errors and reporting them and Autodesk InventorProgramming 166
errors in COM (Autodesk Inventor) 158
Example C++ code shows how to create aCustomTable in an IDW Inventor drawing 143
Excel and iLogic 33
Excel installed on your computer? 312
Excel, VBA and Inventor 38
ExcelIsPresent 312
exception in PutFullFileName 80
exception throwing in Autodesk InventorProgramming in C++ 224
EXE file, Autodesk Inventor Programming in C++ 18
exe, run one from iLogic 29
Exit the editing of a sketch with ExitEdit 90
explode a pattern 439
explode an array 439
Export a workfeature from a Part 196
export WorkFeatures from iParts into Assemblies 188
Exported in a part definition 196
expression display 507
Expression vs Value 358
expressions in a sketch 507
Extents of a part C# 380
extents of a part occurrence in an assembly 49
extrude programatically 242
extrude surfaces (not solids) 433
ExtrudeDefinition in Autodesk Inventor Programmingin C++ 242
extruding faces 433
extruding programatically 274
extruding programatically (AutoDesk InventorProgramming) 178
Extruding sketches with multiple concentric circles 482
Extruding with widening angles 483
extrusion angle 483
extrusion cutting 505
extrusion for cutting objects, programatically 109
extrusion of circles 482
extrusion problems 503
extrusion programatically (AutoDesk InventorProgramming) 178
extrusion to remove material 505
extrusions and profiles (Inventor Programming) 178
extrusions programatically in Autodesk InventorProgramming in C++ 242
extrusuion problems with sketch 503
- F -Face - Hierarchy 290
Face Edge EdgeProxy 236
face enumeration 300
face getting 300
Face Getting hold of the surfaces and faces of a solidobject 300
face normal viewing 513
face viewing along normal 513
FaceFeature listing in C# 392
faces and cylinders C# 374
faces as objects 433
Index 531
(C) 2021 Owen F Ransen
FaceShell Getting hold of the surfaces and faces of asolid object 300
FacesList - Hierarchy 290
factory from member programatically 140
Factory of an iPart in C# 398
factory, listing members 203
FactoryFile 213
FAIL return value for HRESULT codes (E_FAIL) 166
FAILED COM macro and Autodesk InventorProgramming 158
FALSE in VBA 229
FALSE VARIANT_BOOL 229
feature arrays 499
feature deletion 106
Feature deletion in a part 106
feature erasing 106
feature patterns 499
feature removing 106
Feature Suppression of features programatically 221
Feature.IsActive in iLogic 30
FeaturePatternElement getting 191
FeaturePatternElements 190, 221
FeaturePatternElements, suppression of 310
Features and Sketches 507
file exception while saving a file in C# 352
file locations programatically 278
File manager (Inventor programming) 246
file types 484
FileManager and AutoDesk Inventor Programming inC++ 291
filename in the Autodesk Inventor API 209
Filename of referenced doc 118
filename of the part 106
filename, directory name, or volume label syntax isincorrect. 502
Fillet and Trim 512
FindDrawingViewInSheetByName 168
finish sketch 488
fit to view 457
fixed origin in 2d sketches 92
fixed workplane 59
Flat parts list 402
flat sketch editing 477
FlipNormal and WorkPlane constraints 485
FlipNormal failure 59
floating point parameters (ParameterTypeEnum) 235
Flush constraint 258
Flush Mate And Axis Constraint Example 486
Flush vs Mate 497
folded metal cuts listing C# 363
folded metal holes listing C# 363
folded metal holes listing VB 365
folded model hole C# 363
folder in browser 436
Folder, Pane, Browser programatically 83
Folders browser panes 84
Folders in the browser programatically 83
foreach rule, C# 351
form, adding one to iLogic 40
forms and iLogic 40
formulas 487
formulas inside parameters 438
Found conflicts between different versions 326
Free Move 487
Free Rotate 487
full file name of a part 210
FullDocumentName 118
FullDocumentName changing 77
FullDocumentName to get parent of iPart member 140
FullDocumentrName 140
FullFileName exception 80
FullFileName in the Autodesk Inventor API 209
Fully Contrained sketches 459
Function calls in Autodesk Inventor C++programming 224
functions in AutoDesk Inventor 244
fx: 487
- G -general dimensions 128
General Note and text 450
GeneralDimension 126
geometric proxies in Autodesk Inventor C++Programming 260
geometry of a Plane object 132
Get a Document from a Definition 95
get a named object in Autodesk InventorProgramming in C++ 231
get a named workplane 247
Autodesk Inventor Programming in C++ by Owen Ransen532
(C) 2021 Owen F Ransen
get a view from a sheet 168
Get a WorkPlane by name C# 397
Get all the axes in a part 254
Get and Set the name of an Inventor document 255
Get by name C# 397
get document from definition 95
get list of sketches 247
get list of workplanes 247
get name of dimension 137
get name of parameter 137
get number of occurences 216
get occurrences of an assembly 198
Get or get_ differences 286
Get parameters using C# 344
Get PartComponentDefinition from an occurrence 205
get sketch by index 264
get sketch by name 264
Get the name of a part programatically 45
get the name of a sketch programatically 265
Get the part document from the document 156
Get user parameters using C# 344
get_ or Get differences and AutoDesk InventorProgramming in C++ 286
get_... function return values, and Autodesk InventorProgramming 166
get_ActiveDocument 156
get_ActiveDocument in Autodesk InventorProgramming in C++ 255
get_ActiveMaterial 52
get_BOM and BOM rows 85
get_ComponentDefinition and parameters 218
get_ComponentDefinition example 216
get_Constraints for a Mate constraint 160
get_Constraints from anAssemblyComponentDefinition 249
get_Count example 198
get_Count for documents 141
get_Count of dimensions 131
get_DisplayName 255
get_Document and IDispatch** cast 95
get_FileManager 291
get_FileManager for creating documents 148
get_FullDocumentName 118
get_Geometry 2d points in a sketch 97
get_item 300
get_Item and IDispatch**, in Autodesk InventorProgramming 195
get_Item by name 231
get_Item examples in Autodesk InventorProgramming in C++ 288
get_Item for views 288
get_Item for views in a sheet 168
get_item from collection and (IDispatch**) casting 294
get_Item in for loops 287
get_Item parameter type in AutoDesk InventorProgramming 220
get_Item to access objects in an Inventor object list 288
get_Item vs GetItem 224
get_Item vs Item in Autodesk Inventor Programming 220
get_Line from an object 187
get_MassProperties 311
get_Name and BSTR and CComBSTR 272
get_Name of occurence 216
get_Name of view 152
get_Occurrences example 216
get_Profiles 275
get_PropertySets 316
get_RangeBox and Box2d 103
get_ReferencedDocumentDescriptor 118
get_Sketches (Planar) 247
get_SketchPoints 284
get_SubOccurrences 208, 216
get_SurfaceBodies 238
get_SurfaceType 300
get_TransientObjects Autodesk InventorProgramming 176
get_Units crashes C# parameters 361
get_Value double example 63
get_Version 138
get_Workplanes 207, 247
get_XCount 230
get_XCount from a RectangularPatternFeature 197
get_YCount from a RectangularPatternFeature 197
get_YCount in Autodesk Inventor Programming inC++ 230
GetActiveObject does not exist in Marshal 347
GetActiveObject failure Autodesk InventorProgramming 74
GetComponentOccurrenceByName 198
Index 533
(C) 2021 Owen F Ransen
GetCount for documents 141
GetFullDocumentName of a part 210
GetInvAppPtr 20
GetInventorDocTypeDesc 155
GetItem vs get_Item 224
GetItemByName C# 344
GetLocationFoundIn 210
GetModelDataBOMView 85
GetNumDocummentsOpenInInventor 141
GetObject(, "Inventor.Application") 43
GetObjTypeDesc 134
GetOccurrenceName 46
GetPartName 45
GetPartPositionInIamCm position of an occurrence inan assembly 162
GetRetrievableDimensions and picking one of them 128
GetSketchByName 231
GetStdWorkAxisByIndex 170
GetStdWorkPlaneByIndex 82
GetTemplateFile (Inventor programming) 246
getting data about a RectangularPatternFeature 197
Getting hold of the standard workpoint called "CenterPoint" 112
Getting hold of the surfaces and faces of a solidobject 300
Getting into and out of sketches 488
Getting normal part back from iPart with table 424
getting objects by name 231
Getting or running an Inventor Instance 291
Getting the document in Autodesk Inventor C++Programming 156
getting the document type 156
Getting the names of browser folders 84
Getting the value of a parameter in a part C# 357
Getting the version of AutoDesk Inventorprogramatically 138
Getting the version of Inventor programatically 138
Getting the workplanes of a part occurrence in anassembly 207
Getting to the constrain icon in Inventor 489
GetTransGeomPtr 20
GetTransientObjectsPtr 20
getType and ObjectTypeEnum in Autodesk InventorProgramming 134
GetValue of a 197
GetValue() of a Parameter 230
GetWorkAxisByIndex 170
GetWorkAxisByName 231
GetWorkPlaneByName 231
GetWorkPlaneName 46
GetWorkPointByName 231
GetXCount of a rectangular array 230
GetYCount of a rectangular array 230
gkvarEmpty 97
Global or local VBA 35
global pointers for useful objects 20
Global shared variables in iLogic 39
gLogger 313
graphics crash 466
Green and Yellow Dot Constraints 518
green objects in a sketch 463
greyed out iPart 426
Ground and sketch origin 92
Grounded Parts 489
Grounded WorkAxis in an assembly, programatically 114
GUI 455
GUI language of Inventor C# 358
GUID for Sheetmetal and Weldment 246
- H -Headers of partslist 410
HealthStatusEnum 506
Hidden in the .AddIn file 257
hidden lines in an IDW 434
Hide a sketch in a part 102
Hierarchy of objects and AutoDesk InventorProgramming in C++ 290
Hoder 518
hole making from a center point 467
hole size changing 51
HoleCenter programatically 245
HoleDiameter 51
HoleFeature C# 376
HoleFeature HoleFeatureProxy C# 374
Holes in a face of folded metal C# 363
holes in a tube 467
Holes in tubes 490
holes, making them with extrusions 178
Holland 518
hollow tube making manually 492
Autodesk Inventor Programming in C++ by Owen Ransen534
(C) 2021 Owen F Ransen
home view setting customization 457
horizontal constraint in a sketch 463
How to add views to a drawing sheet (Inventor API) 149
How to change colors of the Inventor screen 492
How to change the background of the Inventor screen 492
how to count the number of occurences in anInventor part 258
how to extrude a sketch (Inventor Programming) 178
how to get the name of a component occurrence 198
How to get the parameters of an assembly 218
How to get the RectangularPatterns in aPartComponentDefinition 233
How to get the value of a user or model parameter inAutodesk Inventor C++ Programming 63
how to list constraints in an Inventor assemblyprogramatically 169
how to loop over the constraints in a part document 288
How to make a hollow tube manually 492
how to make an iPart 416
How to move a 3D object 493
How to set the BOM Reference property in a partoccurrence 85
How to start the contrain command 465
how to use get_Item to access objects in an Inventorobject array 288
how to use get_Item with a string name in AutodeskInventor Programming in C++ 288
how to use get_Item with an integer index 288
HRESULT codes in AutoDesk Inventor COMprogramming 158
HRESULT in high level and low level function calls 224
- I -i 489
iam file types 484
icon grounded 489
icon sizes 338
icons 338
icons, marking 511
ide file types 484
IDispatch** cast and get_Document 95
IDispatch, casting to, in Autodesk InventorProgramming 195
IDispatchPtr to DimensionConstraint conversion 137
idw 474
IDW and CustomTable 143
idw file types 484
IDW Views and Sheets programming 168
IDW, create a new one 148
iFeature file .ide file types 484
iLogic and buttons 40
iLogic and LOD 28
iLogic and parameters 39
iLogic and part parameters 30
iLogic and suppression of parts in assemblies 28
iLogic browser 27
iLogic dialog form modification 40
iLogic editing 27
iLogic forms 40
iLogic from C# 347
iLogic global shared variables in iLogic 39
iLogic iProperties 34
iLogic LOD : Setting the Level of Detail with iLogic 28
iLogic MessageBox 80
iLogic quote characters 29
iLogic reference to add to C# project 351
iLogic rules listed from C# 351
iLogic rules, when are they triggered? 41
iLogic running an exe 29
iLogic shared global variables in iLogic 39
iLogic suppression of features in a part 30
iLogic to add parts to an assembly 33
iLogic to change dimensions in sketches 33
iLogic to change parameters 33
iLogic to delete suppressed components 31
iLogic Trace and DebugView 31
iLogic variable declaration 39
iLogic which reads from an Excel file 33
iLogic, adding a new form 40
iMate, add into an assembly based on a workpoint. 97
iMateDefinitions 117
iMates in an assembly and how to list them 117
inch and mm 458
inches , but I want mm 494
inches feet (Inventor Programming) 173
Index 535
(C) 2021 Owen F Ransen
Inches, millimeters, units 513
inclined workplane creation 494
include files in Inventor Programming 75
include SafeArrayUtil.h 143
including WorkFeatures for iparts 188
independent object from pattern 439
indices of planes in a part, C# 395
indices of standard planes in a part C# 395
InitInstance MFC 18
Inseperable, BOM 402
Insert constraint 494
Insert constraint (Perno Foro) 430
Insert constraint does not worl 515
insert, Autodesk Inventor Programming in C++ 216
Inserting an inclined workplane 494
inside Inventor, running a C# plugin 328
Installing the SDK 15
integer variant 287
intellisense 75
intellisense not working 282
interference 465
internal name of material 47, 52
internal units of Autodesk Inventor Programming 173
InternalName vs DisplayName 81
Interrogating rectangular patterns in AutodeskInventor Programming 197
intersection between line and plane to get aWorkPoint 113
Invalid parameters in COM call, and AutodeskInventor Programming 166
Inventor Apprentice 496
Inventor CLSIDFromProgID 312
Inventor COM error reporting 166
Inventor document types 155
Inventor documents programatically 224
Inventor errors and reporting them 166
Inventor from inside Access VBA 43
Inventor part opening programatically API 79
Inventor Programming in C++ introduction 15
Inventor Project Wizard 78
Inventor Projects 503
Inventor references C# 322
Inventor User Defined Properties 38, 314
Inventor VBA and Excel 38
Inventor warnings 166
Inventor.Application 291
Inventor.Application VBA 43
Inventor.AssemblyDocument orInventor.PartDocument C# 355
Inventor.exe instance 291
Inventor.PartDocument orInventor.AssemblyDocument C# 355
InventorUtils.h and stdafx.h 75
InvErrorHandling.cpp 166
Invisibility of a part's WorkPlane in an assembly 211
Invisibilize components in a collection 295
invisible 478
invisible and visible work features 211
invisible Inventor app 185
invisible opening of parts and assemblies 149
Invisible sketch 102
invisibly open and assembly 68
iPart - standard vs custom 417
iPart author 417
iPart author parameter visibility 174
iPart Author to make custom iParts 419
iPart Author, suppression of features 424
iPart creation 416
iPart factory parent from child member 140
iPart file types 484
iPart insertion problems 502
iPart Member 416
iPart Member and PartNumber 417
iPart table programatically Compute and Suppress 223
iPart table value reading C# 398
iPart table, add a custom column 425
iPart tables suppression of features 424
iPart to normal part conversion 424
iPartFactory listing the members 203
iPartMember programming 206
iParts (custom, how to make and use them) 419
iParts and Assemblies and WorkFeatures 188
iParts and WorkFeatures 188
iParts and WorkPlane, WorkPoint, WorkAxis 188
iParts general info 416
iPartTableCell and iPartTableRow 203
iPartTableRow and iPartTableCell 203
ipj 503
ipj file types 484
ipn file types 484
Autodesk Inventor Programming in C++ by Owen Ransen536
(C) 2021 Owen F Ransen
iProperties and iLogic 34
iProperties of an Inventor DOC using C# 343
iProperties of an Inventor document 316
iProperties overview 314
iProperties using C# 343
iProperties VBA 44
iProperties, add a custom value programatically 318
iProperties, create a new property set 320
iProperties, read the value of a custom property 321
iProperty existence, C++ 65
iProperty sets in iLogic and VBA 38
iProperty value getting C++ 65
ipt file types 484
Is Nothing example 43
IsActive feature in iLogic 30
IsPatternElement and iLogic 31
Italian Compute and Suppress (Calcola e Sopprimi) 223
Item by name example C# 397
Item parameter type 220
Item vs get_Item in Autodesk Inventor Programming 220
ItemByName C# 344
Items in lists by string C# 376
- J -Jelte de Jong 332
- K -kA3DrawingSheetSize drawing page sheet size 71
kA4DrawingSheetSize drawing page sheet size 71
kAdjustToDirection1 271
kAdjustToDirection2 271
kADrawingSheetSize drawing page sheet size 71
kArbitraryViewOrientation = 10763, 304
kAssemblyDocumentObject 134, 156, 246, 275
kAssemblyDocumentObject VBA 37
kBackViewOrientation 149
kBackViewOrientation = 10756, 304
kBDrawingSheetSize drawing page sheet size 71
kBottomViewOrientation 149
kBottomViewOrientation = 10757, 304
kBottomViewOrientation in sheets 149
kBSplineSurface 300
kCannotComputeHealth 11783 Object cannot beevaluated. 506
kCDrawingSheetSize drawing page sheet size 71
kCircleCurve2d in a Profile C# 363
kComponentOccurrenceObject in Autodesk InventorProgramming 134
kConeSurface 300
kCurrentViewOrientation 149
kCustomDrawingSheetSize drawing page sheet size 71
kCylinderSurface 300
kDefaultPageOrientation 70
kDefaultPageOrientation drawing page orientation 71
kDefaultSystemOfMeasure 246
kDerivedParameter : Parameters automaticallycreated from derived component. 235
kDesignElementDocumentObject 156
kDrawingDocumentObject 246
kDrawingDocumentObject creating one 148
kEnglishSystemOfMeasure 246
kFeaturePatternElementObject 134, 190
kFitted pattern spacing 271
kFitToPathLength pattern spacing 271
kForeignModelDocumentObject 156
kFrontViewOrientation 149
kFrontViewOrientation = 10764, 304
kg mass Inventor Programming 173
kHiddenLineDrawingViewStyle 154
kHiddenLineDrawingViewStyle, , Inventor API 149
kHiddenLineRemovedDrawingViewStyle 154
kIdentical 271
kIsoBottomLeftViewOrientation = 10762, 304
kIsoBottomRightViewOrientation = 10761, 304
kIsoTopLeftViewOrientation = 10760, 304
kIsoTopRightViewOrientation = 10759, 304
kLandscapePageOrientation 70
kLandscapePageOrientation drawing page orientation 71
kLeftViewOrientation 149
kLeftViewOrientation = 10758, 304
kLineSegmentCurve2d C# 392
kMetricSystemOfMeasure 246
kModelParameter : Parameter created automaticallyby Inventor when a command requires it. 235
kModelParameterObject 134
Index 537
(C) 2021 Owen F Ransen
kObjectCollectionObject 134
kPartComponentDefinitionObject 134
kPartDocumentObject 156, 246
kPlaneSurface 300
kPortraitPageOrientation 70
kPortraitPageOrientation drawing page orientation 71
kPresentationDocumentObject 156
kReferenceFeatureObject is a derived part C# 397
kReferenceParameter : Parameter createdautomatically by Inventor while creating a drivendimension, for example. 235
Kriek 518
kRightViewOrientation 149
kRightViewOrientation = 10755, 304
kRightViewOrientation in sheets 149
kSATFileDocumentObject 156
kShadedDrawingViewStyle, Inventor API 149
kSphereSurface 300
kTableParameter : Parameters created from a table;like a spreadsheet. 235
kTopViewOrientation 149
kTopViewOrientation = 10754, 304
kTorusSurface 300
kUnknownDocumentObject 156
kUpToDateHealth 11778 Object is up to date. 506
kUserParameter : Parameters explicitly created bythe user. 235
kWorkAxisObject 194
kWorkPlaneObject 134, 194
kWorkPointObject 134, 194
kWorkPointProxyObject 134
- L -Landscape and Portrait orientation getting and setting 70
language of Inventor interface C# 358
LanguageCode C# 358
LanguageName C# 358
Leefsma 518
length (Inventor Programming) 173
LengthUnits C# mm or cm 389
Level of detail and suppress 426
Liang 518
library of components 503
Line create a geometric object 114
Line, getting from an object 187
LinePtr 294
LinePtr getting example 309
Lines, Adding lines text and circles to aDrawingSketch 90
linetypes in sketches 437
List (filtered) of parts in an assembly 104
List all planes in a part, C# 395
list all rules in an Inventor document using C# 351
List iMates in an assembly 117
list occurences inside an assembly 216
list of constraints 288
list of constraints in an assembly programatically 169
list of Inventor objects and get_Item 288
list of objects, ObjectCollection 176
List of objects, ObjectsEnumerator 235
list of workplanes 251
Listing 2d points in a sketch 97
Listing constraints in an assembly programatically 201
Listing cuts in a face of folded metal C# 363
Listing documents open in Inventor with VBA 36
Listing holes in a face of folded metal C# 363
Listing holes in a face of folded metal VB 365
Listing iProperties of an Inventor document 316
Listing members in an iPartFactory programatically 203
Listing parameters in an assembly, C# 356
Listing RevolveFeatures of a part programatically 309
Listing the names of axes in a part 254
Listing the profiles of a face in C# 392
Listing types of dimensions in a view 137
load AddIn suppression 453
loading the addin DLL in Autodesk Inventor C++Programming 263
Local or global VBA 35
LOD and iLogic 28
LOD Level Of Detail 426
Logger, gLogger 313
look at command 477
loop of edges 515, 517
loop over assets 47, 52
loop over materials 47, 52
Loop over occurrences in an assembly in C# 345
loop over open documents 141
Autodesk Inventor Programming in C++ by Owen Ransen538
(C) 2021 Owen F Ransen
Loop over part occurrences in an assembly 106
loop over views in a sheet 168
Looping over browser folders 84
Looping over components inside an assembly in C# 345
looping over parts in an assembly 104
LPCWSTR and BStr in Names of features 254
- M -maetrial name 47, 52
Major version 138
make a hole extruding 178
making a tube with holes in it 467
making an iPart 416
manipulator snap 458
manual dimension deletion 445
marking menu 476, 511
Marshal.GetActiveObject does not exist 347
mass kg (Inventor Programming) 173
mass properties programatically 311
Mass Volume Calculation 445
Mate constraint with two planes programatically 160
Mate vs Flush 497
material and color of a solid 455
material asset purging 303
material category 47, 52
material display name 47, 52
material error 454
material internal name 47, 52
material looping 47, 52
material problem, strange 454
materials and assets 52
materials API 52
materials editor 52
Matrix and Vector 174
matrix for rotation 185
matrix in Autodesk Inventor Programming in C++ 291
matrix point vector in Autodesk InventorProgramming 183
Matrix Vector and SetTranslation, C# 380
measurement units 246
Member and PartNumber in iParts 417
member name of an iPartFactory programatically 203
Member not found error in C# add-in 353
member of an iPart in C# 398
member to parent getting 140
menu customization 476
menu, marking 511
message box, C# 342
MessageBox vs MsgBox in iLogic and VBA 80
metal concrete wood 47, 52
MethodAdd vs Add 224
MFC compiling for Autodesk Inventor Programming 78
MFC InitInstance 18
millimieters C# 389
minibar autofade option 498
Minor version 138
mirrored parts suppressed 509
MK_E_UNAVAILABLE 0x800401e3 AutodeskInventor Programming 74
mm and inch 458
mm cm (Inventor Programming) 173
mm instead of inches 494
mm or cm in C# units 389
mm parameters in Autodesk Inventor Programmingin C++ 235
Mm, Units, Inches 513
Model and User parameters programatically inAutodesk Inventor Programming in C++ 57
model data BOM view 85
Model Parameter Change 477
Model Parameter Display 477
model parameter setting with C# 358
Model Parameter Type 134
model parameters 416
model parameters vs user parameters. 487
model parameters, getting the value programatically 63
ModelParameters in C# 356
ModelValue of a dimension 126
mouse gestures 511
Move a 3D object 493
MoveFile warning, Autodesk Inventor Programming 78
moving a workplane 475
MSB3073 error 302
MSB3075 in Inventor Programming 74
MSB3277: Found conflicts between different versions 326
Index 539
(C) 2021 Owen F Ransen
MsgBox vs MessageBox in VBA and iLogic 80
multi user 513
Multiple Document Viewing in Inventor 513
multiple lines within table cells 146
- N -Nagy 518
Name an assembly 208
Name of a part programatically 45
Name of a plane in a part definition 196
name of a sketch changing 120
Name of a WorkPoint, how to set it 112
name of an Inventor sketch programatically 271
name of an occurrence 198
name of an occurunce 46
Name of document, getting and setting 255
name of DrawingView 152
name of occurrence 118, 216
name of PartComponentDefinition 45
name of view 152
Name vs DisplayName 52
Name, DisplayName vs InternalName 81
Name, InternalName vs DisplayName 81
Name, set the name of a WorkFeature example 196
named objects, getting them 231
names and sketch objects 225
names of features, Name 254
Names of objects inside sketches in AutodeskInventor Programming in C++ 225
names of parameters which control dimensions 137
NameValueMap C# 344
naming model parameters 487
Negative Dimensions 127
new assembly and new document (creation of) 275
new browser folder 436
new document and new assembly (creation of) 275
new drawing document 148
new DWG document 148
new features and old patterns 449
new IDW document 148
New line within table cells 146
new Part programatically 177
new views in a sheet 149
no inference 97
No visible unadaptive sketches 498
non coplanar parallel constraint 400
normal face viewing 513
normal of a plane 160
Normal of a Plane object programatically 132
Normal, BOM 402
Nothing VBA example 43
null pAsset 47
NULL return values , and Autodesk InventorProgramming 166
NULL VARIANT 97
number of documents open in Inventor (C++) 141
- O -object descripion getting function 134
Object Hierarchy 290
object types 134
ObjectCollection Autodesk Inventor Programming 176
ObjectCollection creation (parts in an assembly) 104
ObjectCollections in the Inventor API 176
ObjectsEnumerator and Patterns 234
ObjectsEnumerator use example 113
ObjectsEnumerator, a list of objects in AutodeskInventor Programming in C++ 235
ObjectTypeEnum and getType 134
Occurences, Autodesk Inventor Programming in C++ 216
occurences, how to get the programmatically 198
occurrence adding 201
Occurrence and EdgeProxy 236
occurrence name 118
occurrence name getting 46
OccurrencePatterns inside Assemblies 309
occurrences and component definitions 216
occurrences and iPart members 206
occurrences and PartComponentDefinition of them 205
Occurrences as Xrefs 272
occurrences assemblies custom ipartsprogramatically 214
occurrences, sub, in Autodesk Inventor C++programming 208
occurrences, workplanes, parts, assemblies 207
offset from plane command 475
Autodesk Inventor Programming in C++ by Owen Ransen540
(C) 2021 Owen F Ransen
offset of a plane 456
offset plane and sketch 295
Offsetting a workplane 475
Old Versions To Keep 452
OldVersions directory of backups 452
OLECHAR BSTR wchar_t 272
OnExecute of a button 338
open a document programatically 224
open a part from a view 133
Open an assembly programatically 68
Open an Inventor assembly programatically 68
Open an Inventor file using C# 344
Open an Inventor part programatically 79
open invisible 149
OpenAssembly function 68
OpenPart API for Inventor 79
OpenWithOptions 344
Optional parameters and empty COM values inAutodesk Inventor Programming in C++ 244
options programatically 278
Options Settings 452
options, sketch plane, part tab 507
Orientation of a sheet on a page 71
orientation of a WorkPlane in C# 381
Orientation of occurrences adjusted to direction 1. 271
Orientation of occurrences adjusted to direction 2. 271
Orientation of patterns 271
orientation of the sheet 70
orientations of a view in a drawing 304
origin of a work axis programatically 294
Origin point 112
Other column in iPart tables 425
Otterman 518
out of memory errors in call to AddBaseView 149
Override a total quanitity in a BOM. 87
overrides, materials, clear them 454
overwite exising file exception C# 352
overwriting existing Inventor files with SaveAs in theAutodesk Inventor API 208
- P -Pack And Go, getting individual components from it. 427
PageOrientationTypeEnum 70
Pane, Browser, Folder programatically 83
panes in C# 355
Parallel constraint, not coplanar 400
Parallel planes constraints programatically 49
Parallel planes programatically 49
parallel workplanes 251, 475
Param.Value casting in C# 357
parameter adding 478
parameter adding programatically 103
parameter deletion 477
parameter diameter 459
parameter erasure 477
parameter export from a part 174
Parameter getting in C# 344
parameter getting programatically 218
parameter getting using C# 356
parameter in a part C# 357
parameter name changing 477
parameter of axis constraint 461
parameter setting with C# 358
Parameter Type 134
parameter types (ParameterTypeEnum) in AutodeskInventor Programming in C++ 235
Parameter units 235
parameter visibility at a higher level 174
ParameterPtr in COM for Inventor 230
parameters 487
parameters and C# 358
parameters and iLogic 30
parameters API 218
parameters for driven dimensions 478
parameters in a custom iPart programatically 214
Parameters in Inventor programatically 57
parameters invalid in COM call, and AutodeskInventor Programming 166
parameters with formulas 438
parameters, model and user, how to get themporgramatically 63
Parent objects of patterns 191
parent of an iPart member 140
part .ipt file types 484
Part Close programatically 155
Part containing sketches in Autodesk Inventor C++Programming 264
Part Document creation 177
part document from the document 156
Part document opening API 79
Index 541
(C) 2021 Owen F Ransen
part document pointer from a document pointer. 255
part files file types 484
Part Lists programatically 99
Part Name programatically 45
Part occurrences in an assembly, how to loop overthem 106
part parameters and iLogic 30
part position 174
Part vs Assembly for work things 440
part workfeatures in an assembly 211
PartComponentDefinition and occurrences 205
PartComponentDefinition and PartDocument openthe file 79
PartComponentDefinition and RectangularPatterns 233
PartComponentDefinition and Sketches 264
PartComponentDefinition from an occurrence 205
PartComponentDefinition getting 22
PartComponentDefinition name 45
PartComponentDefinition, get its document 95
PartDefinition from Doc 249
PartDocument and PartComponentDefinition 249,264
PartDocument and PartComponentDefinition openthe file 79
PartDocument creation programatically 177
PartDocument from PartComponentDefinition 95
PartDocument or AssemblyDocument C# 355
PartFeatureExtentDirectionEnum 178
PartFeatureOperationEnum 178
Participating occurrences 109
PartList programatically 99
PartList Style (Default) 410
PartNumber and Member in iParts 417
Parts and Constraints from a programmer's point ofview in Autodesk Inventor C++ Programming 262
parts and views, open a part from a view 133
Parts in an assembly object collection 104
Parts list 402, 404
parts list bounding box 103
Parts List Column Order 410
Parts List Style (Default) 410
Parts List vs BOM 401
Parts List, remove an item 404
Parts Only (disabled) problem 405
parts only BOM view 405
Parts Only Parts List 402
Partslist vs BOM 401
PartsListCell programatically 99
PartsListRow programatically 99
PartsLists programatically 99
pAsset is null 47
path for tlb files 282
path length pattern spacing 271
path to RxInventor.tlb 282
pattern (how ro add a feature to an existing pattern) 449
Pattern count = 1 ? 194
Pattern Counts are strange 194
pattern element deletion 441
Pattern element suppression, first element in apattern cannot be suppressed 310
Pattern Feature Suppression of featuresprogramatically 310
Pattern inside a sketch 498
pattern making 499
Pattern name 194
pattern of features 499
pattern of parts programatically 309
pattern spacing Occurrences separated by specifieddistance. 271
pattern spacing kDefault 271
pattern, explosion 439
pattern, remove object from one. 439
PatternElements 221
PatternElements and iLogic 31
PatternElements in the Inventor API 190
PatternElements, suppression of 310
PatternOrientationEnum, Constants identifying thepattern orientation method. 271
Patterns, contents of programatically 191
pDocuments->Add 149
Perno Foro (Insert) constraint 430
Phantom, BOM. 402
placed features 512
Placing a work axis 514
placing parts in space 174
PlanarSketch 178
PlanarSketch (adding to workplane) 247
Plane adding by offset from an existing plane 295
plane by offset from another plane 295
Plane object programatically getting its geometry 132
Autodesk Inventor Programming in C++ by Owen Ransen542
(C) 2021 Owen F Ransen
Plane on the surface of a tube at an angle 501
plane position editing 456
Plane Surface 300
planes in a part, C# 395
plugin Activate function 342
Plug-in automatic load suppression 453
plugin in C# 328
plugin manager, removal of a plug in 341
plugin removal 341
point 2d 3d in Autodesk Inventor Programming 183
point adding to tube manually. 450
Point create a geometric object 114
point display 245
Point in center of a hole 517
point offset 426
point vector matrix in Autodesk InventorProgramming 183
Point2d Transient Geometry 183
Point3d Transient Geometry 183
Points and CenterPoints in Autodesk InventorProgramming in C++ 245
points in a sketch programatically 284
points in a sketch, listing their coordinates 97
Portrait and Landscape orientation getting and setting 70
Position a 3D object 493
position of a part in space 174
position of a table in a sheet. 146
position of an occurrence in an assembly,GetPartPositionInIamCm 162
position of part in assembly, C++ 162
position of text in a sheet 146
Positioning objects in a Sheet. 146
post build event step 302
printf BSTR 272
problems encountered while executing thiscommand. 503
Problems encountered while saving the document. 502
Problems with sketch extrusion and revsurf 503
Profile and kCircleCurve2d C# 363
Profile example (extrusion) 242
profile of two circles 467
profile, what is it? 275
ProfilePath and CutFeature C# 363
profiles and AddForSolid 274
profiles and extrusions (Inventor Programming) 178
profiles and sketches 275
programatically add a rectangle to a sketch 284
programatically occurrences assemblies customiparts 214
Programming Autodesk Inventor in C++ to add acircle to a sketch 22
Programming Inventor in C++ introduction 15
Project file 503
project file file types 484
project file programatically 278
project file workspace 210
project files programatically 307
project template default setting 494
projected views and base views 153
Properties, adding 320
Property sets in iLogic and VBA 38
Property sets of an Inventor document 316
PropertySet, new 320
proxies (geomeatrical) 260
proxies and constraints (planes) Autodesk InventorProgramming 160
proxies in constraints 201
Proxies, why and what? in Autodesk InventorProgramming 163
Proxy in Autodesk Inventor Programming 163
Proxy in C# 374
proxy of an assembly workplane in an assembly 379
Purchased, BOM 402
purge assets 303
purge material assets 303
push pin grounded 489
put assembly inside another assembly,programatically 101
put_AffectedOccurrences 109
put_FullFileName example in the Autodesk InventorAPI, Save function 209
put_Name 112
put_Name and CString 120
put_Name and wchar_t problems 120
put_Name of view 152
put_Name, how to use it 120
put_Reference 85
put_Suppressed 221
put_Suppressed in patterns 310
Index 543
(C) 2021 Owen F Ransen
put_Visible 213
put_Visible for sketches 102
PutFullFileName exception 80
Putting 2d dxf files in 3D assemblies 505
- Q -QI QueryInterface 139
QTY in BOMs and partslists 413
quantity in a BOM programatically 87
QueryInterface and Release Etc 139
QueryInterface example 137
QueryInterface(DIID_PartDocument 156
quotes in VB strings 29
- R -radians and degrees and Autodesk InventorProgramming 173
radians and degrees SetToRotation 185
radius in a workaxis constraint 111
radius of hole, how to change 51
RangeBox of a parts list 103
Reading values from an iPart table in C# 398
ReadOnly opening 344
rectangle in sketch and AutoDesk InventorProgramming in C++ 284
rectangle, add it to a sketch 108
rectangles in sketches programatically 108
rectangular pattern 499
rectangular pattern in sketch 498
Rectangular pattern name and counts 194
Rectangular pattern of parts programatically 309
rectangular patterns 233
RectangularArray GetXCount 230
RectangularPattern contents programatically 191
RectangularPattern HealthStatusEnum 506
RectangularPatternFeature, getting data about one 197
RectangularPatterns and PartComponentDefinition 233
red and blue workplane sides 485
redefine the components of an existing pattern 449
Reference property of a part occurrence 85
ReferenceComponent 117
ReferenceComponents C# 397
referenced doc filename 118
Referenced Document of a View 118
referenced documents in a DrawingView 88
Referenced, BOM 402
ReferencedDocumentDescriptor 118
ReferencedDocumentDescriptor to get parent 140
ReferencedFileDescriptor 46
ReferencedFileDescriptor and ComponentOccurence 198
ReferencedFileDescriptor and name of a part 45
ReferenceMissing in a component occurrence 223
regen = Update 221
registering COM DLL 281
registration of Visual Studio Inventor Wizard failure 78
Registry Free AddIns 272, 281
Registry Free AddIns in Inventor Programming 74
regsvr32 281
regsvr32 in Inventor Programming 74
remove a C# plugin from the plugin manager 341
Remove a feature in a part 106
remove a workaxis programatically 295
remove an element from a pattern 439
Remove something from a Parts List 404
Remove table from an iPart 424
Removing a constraint 477
removing a driven dimension 477
Removing material with the cut extrusion command 505
rename warning, Autodesk Inventor Programming 78
ResultFeatures and Patterns in Autodesk InventorProgramming in C++ 234
ResultFeatures and workplanes, workpoints,worksurfaces 234
retrievable dimension showing 128
Retrievable Dimensions 120
return codes from COM (Autodesk Inventor) 158
ReturnAndShowCOMError 166
revolution problems with sketch 503
RevolveFeature listing C++ 309
rgs file for Inventor AddIns, what is it? 272
Right hand coordinate system in Inventor 27
ROT Running Object Table Autodesk InventorProgramming 74
rotate an object inserted as an occurrence in anassembly 185
rotate and translate an iPart 174
Autodesk Inventor Programming in C++ by Owen Ransen544
(C) 2021 Owen F Ransen
rotate around the Z Axis 185
rotation around the X axis in Inventor programming 185
rotation around the Z axis in Inventor programming 185
rotation of objects programatically in AutoDeskInventor 185
rotation with FlipNormal (constraints) 160
RowCount is strange 194
rules and buttons in iLogic 40
rules of iLogic from C# 347
rules, iLogic, and C# 351
Run Inventor from C# 322
Run Inventor from VBA 43
running Inventor 291
RunRule from C# 347
RxInventor.tlb and AutoDesk Inventor Programmingin C++ 282
RxInventor.tlb path in Autodesk InventorProgramming in C++ 282
RxInventor.tlh 282
rxinventor.tlh and enum values 134
RxInventor.tli 282
- S -S_FALSE com success macro and AutodeskInventor Programming 158
S_OK and S_FALSE, and Autodesk InventorProgramming 166
S_OK com success macro and Autodesk InventorProgramming 158
SAFEARRAY and doubles 96
SAFEARRAY and strings 96
SAFEARRAY with CustomTables 143
SafeArrayDestroy 96
SafeArrayUtil.h include 143
Samples (UserTools.msi) 15
save not working 170
Save programatically in C# 352
Save programatically in the Autodesk Inventor API 209
SaveAs and Close Autodesk Inventor API C++ 211
SaveAs gotcha 208
SaveAs programatically in the Autodesk Inventor API 208
SaveCopyAs 208
saving apparently disabled 170
Saving without dialogs 155
scale of view drawing 474
SDK Installing 15
set document filename when saving Inventordocuments 209
set name of an assembly 208
set name of an IPT or assembly FullFileName 80
Set the visibility of all workplanes in a part 253
set_Name (you mean put_Name) 112
SetDistanceExtent for extrusions 178
SetEnvironmentVariable warning, Autodesk InventorProgramming 78
setting the visibility if Inventor 185
settings of the document 452
Settings Options 452
SetToRotation 185
SetTranslation 174
SetTranslation (pVector,VARIANT_TRUE) 174
SetTranslation, C#, in cm 380
SetWorkPlaneVisibility 211
Shared global variables in iLogic 39
Sheet and dimensions 120
Sheet coordinate system 146
Sheet Metal C# 363
Sheet Metal GUID 246
sheet metal profile C# 392
Sheet Metal VB 365
Sheet orientation 70
Sheet View Orientations 304
Sheet View Referenced Document 118
sheets, views, drawings, Inventor C++ API 149
Sheets.Add 71
Shekar 518
shell getting 300
Shiue 518
Show a dimension programatically 128
Show hidden lines in a drawing manually 434
ShowCOMError and Autodesk Inventor Programming 166
Showing dimensions temporarily 507
showing expressions in a sketch 507
sign inside parameter formulas 438
sign of dimenions 127
SilentOperation 170
SilentOperation and save dialogs 155
single user 513
Index 545
(C) 2021 Owen F Ransen
sketch a rectangle programatically 108
sketch and part 264
Sketch by name 231
Sketch constraints 518
sketch edit 488
sketch expressions 507
sketch extrusion (Inventor Programming) 178
sketch finish 488
sketch geom to construction geom 503
sketch name getting 271
sketch name programatically 265
sketch name setting 271
sketch offset from a plane 295
Sketch offset from plane (in assemblies) 295
sketch origin constrain and AddGround 92
sketch patterns 498
sketch plane 507
sketch plane default 467
sketch plane from 3 points 515
sketch, add a circle to it 81
Sketch, Add a DrawingSketch to a DrawingDocument 89
sketch, add to assembly or part 61
sketch, exiting 488
sketch, getting into 488
Sketch, hiding it 102
SketchCircle, adding a circle to a sketch 81
SketchCircles in Autodesk Inventor C++Programming 81
Sketches and Features in Inventor 507
sketches and names 225
sketches and parts 264
sketches and profiles 275
sketches and workplanes programatically 265
Sketches in an Inventor Part 264
sketches on standard planes 265
sketches programatically 242
SketchPoint coordinate getting 97
SketchPoint in Autodesk Inventor Programming inC++ 284
Skipping missing components programatically 223
SkipSave when Close in Inventor API 211
SkipSave when closing a document 155
smart pointers, COM and Autodesk Inventorprogramming 22
snap changing for 3D dragging 458
snap spacing 3D 458
snaps hard and soft 518
solid feature 2d sketch 507
solid material and color 455
Sphere Surface 300
SQRT inside parameter forumlas 438
square bracket item in C# lists 376
standard iPart 417
standard planes and sketches 265
standard planes in a part C# 395
standard units in Inventor 173
standard work axis 170
Standard WorkAxes in C# 385
Standard WorkPlane getting 82
Startup Add-In automatic load suppression 453
Static BOM quantity 413
Static quantity in a BOM programatically 87
std workpoint "Center Point" getting hold of itprogramatically 112
stdafx.h and InventorUtils.h Autodesk InventorProgramming 75
stop addin load 453
Strange material problem 454
strings in Inventor and OLE and COM 272
strTemplateFile 246
Styles 410
SubOccurrences 216
SubOccurrences in the Autodesk Inventor C++ API 208
substitution in parts lists 404
suppress a feature in an iPart table 424
Suppress and Compute and from an iPart tableprogramatically 223
suppress feature 221
suppress feature in a pattern in Autodesk InventorProgramming in C++ 310
Suppress or Compute in iPart tables 424
Suppress parts 426
Suppressed boolean API 221
suppressed components deletion with iLogic 31
suppressed parts and mirrors thereof 509
suppression of features in a part using iLogic 30
Suppression of features in patterns programatically inAutodesk Inventor C++ Programming 310
Suppression of features parametrically using the iPartAuthor 424
Suppression of features programatically in AutodeskInventor Programming 221
Autodesk Inventor Programming in C++ by Owen Ransen546
(C) 2021 Owen F Ransen
Suppression of parts in assemblies iLogic 28
surface bodies 300
surface enumeration and AutoDesk InventorProgramming in C++ 300
surface extrusions 433
SurfaceBodies and EdgeProxies 236
SurfaceBodiesList - Hierarchy 290
SurfaceBody - Hierarchy 290
SurfaceTypeEnum in Autodesk InventorProgramming in C++ 300
switch on the browser pane 488
SysFreeString 272
- T -table cells with multiple lines 146
table editing of custom iparts 422
table iparts 424
table of an iPart readnig them 398
table suppression of iPart featues 424
table, add a custom column in an iPart table 425
Tables in Sheets and Drawings 143
tangent to surface through point 501
temperature (Inventor Programming) 173
template file in Autodesk Inventor Programming inC++ 246
template files 509
TemplateFile 291
text in an Inventor document 450
text tables in IDW files 143
The database blah blah .ipt could not be saved 502
The filename, directory name, or volume label syntaxis incorrect. 502
The hierarchy is like this: 290
throw exceptions 224
time (Inventor Programming) 173
tips and tricks for Autodesk Inventor programming inC++ 25
tlb 282
TLB RxInventor 282
tlh 282
TLH RxInventor 282
TLI RxInventor 282
Torus Surface 300
total quantity in BOM row 87
TotalQuantityOverridden 87
Trace in iLogic 31
Trace.WriteLine 31
transient geometry 291
transient geometry and AutoDesk InventorProgramming in C++ 174
Transient geometry and geometrical proxies 260
transient geometry points and SketchPoint 284
TransientGeometry 174
TransientGeometry Autodesk Inventor Programming 183
TransientObjects in the Inventor API 176
translation 174
tricks and tips for Autodesk Inventor programming inC++ 25
triggering iLogic rules 41
Trim and Fillet 512
TRUE in VBA 229
TRUE VARIANT_BOOL 229
tube hollow manually 492
Tubes with holes 490
type library 282
type of objects 134
types of dimension 137
types of parameters (ParameterTypeEnum) 235
- U -ul as a dimension 513
unadaptive sketches 498
UNICODE and ASCII 272
UNICODE, Autodesk Inventor Programming in C++ 22
UNICODE, wchar_t and programming Inventor 272
unitless 513
unitless parameters programatically, "ul" 103
units 458
units (internal) 173
Units does not exist in C# parameters 361
units in a sheet coordinate system 146
units in a template file 246
units of parameters 235
units when programming Autodesk Inventor 173
units, inches or mm programatically 246
Units, Inches, Mm 513
UnitsOfMeasure C# 389
UnitVector, getting an axis 187
Unsupress parts 426
upcast from AssemblyDocument to Document 318
Index 547
(C) 2021 Owen F Ransen
Update a Part after a parameter change 57
Update custom iproperty with VBA and iLogic 38
Updating a part or assembly C# 358
User and Model parameters programatically 57
user defined type not defined error and Excel 38
User Interface 455
user parameter setting with C# 358
user parameters and virtual components 406
user parameters as dimensions 487
User parameters in C# 344
user parameters, getting the value programatically 63, 223
UserInterfaceVersion in .AddIn files for Inventor 286
UserParameters and ModelParameters 57
UserParameters in C# 356
- V -Value casting in C#, parameters 357
value of a custom iProperty C++ 65
value of a parameter in a part C# 357
Value vs Expression 358
variables in iLogic 39
variant (default) 287
variant (empty) 287
VARIANT and CComVariant and AutoDesk InventorProgramming in C++ 287
VARIANT arrays of strings 214
VARIANT empty 97
VARIANT which is an array of doubles 143
VARIANT, an array of double values for Inventor 147
VARIANT_BOOL Autodesk Inventor Programming inC++ 229
VARIANT_FALSE 229
VARIANT_TRUE 229
Vault 513
VB.NET 275
VBA 275
VBA and iLogic Update custom iproperty 38
VBA custom iProperties 44
VBA Default.ivb 35
VBA document type 37
VBADocumentTypeEnum.kAssemblyDocumentObject 37
VBA Excel and Inventor 38
VBA Inventor from inside Access 43
VBA Inventor.Application 43
VBA iProperties 44
VBA kAssemblyDocumentObject 37
VBA listing documents 36
VBA local or global project 35
VBA MsgBox 80
VBA Run Inventor 43
VBA running an exe 29
VBA to C++ 244
VBA to change dimensions in sketches 33
VBA to change parametes 33
Vector and Matrix 174
Vector and SetTranslation, C# 380
Version of Inventor, getting it programatically 138
vertical constraint in a sketch 463
View and zoom 46
view assembly as a drawing 474
View Cube 304
view face 513
view face normal 513
view from a sheet 168
view names 152
View orientation, Inventor API 149
View orientations 304
View Referenced Document 118
view scale 474
View scale, Inventor API 149
view style 154
View, what documents is it looking at... 88
Viewing 2d dxf files in 3D assemblies 505
Viewing Multiple Documents in Inventor 513
ViewOrientationTypeEnum 304
ViewOrientationTypeEnum of views in sheets 149
views and parts, open a part from a view 133
Views Sheets Drawings programatically 168
views, base 149
views, sheets, drawings, Inventor C++ API 149
Virtual component alternative in a BOM 413
virtual components and user parameters 406
virtual components in a BOM 406
Virtual components, how to 406
visibility 478
Visibility of a part's WorkPlane in an assembly 211
Visibility of all workplanes in a part 253
Autodesk Inventor Programming in C++ by Owen Ransen548
(C) 2021 Owen F Ransen
Visibility programatically 213
Visibilize components in a collection 295
visible and invisible work features 211
visible Inventor app 185
Visible programatically 295
Visible sketch hiding 102
Volume Mass Calculation 445
VT_I4 COM data type and AutoDesk InventorProgramming in C++ 272
- W -Walmsley 518
Ward 518
wchar_t 22
wchar_t and CComBSTR in the Autodesk InventorAPI 208
wchar_t, UNICODE and programming Inventor 272
Weight properties programatically 311
weld file file types 484
weldment file .iam file types 484
Weldment GUID 246
what are PatternElements in the Inventor API? 190
What sort of WorkFeature is this in AutodeskInventor Programming? 194
When do iLogic rules run? 41
where .AddIn files are placed 263
where sketches are stored in an Inventor Part 264
why my objects blue 463
why my objects still green 463
wide char 272
WinError.h and Autodesk Inventor 158
Wizard 15, 302
Wizard failed to register 78
wood concrete metal 47, 52
Work Axis Thru Circular Hole 514
WorkAxes (Standard) in C# 385
WorkAxes at assembly level 429
WorkAxes listing names of 254
WorkAxes programatically 170
WorkAxis collection 170
workaxis constraint margin 111
workaxis constraints 111
Workaxis constraints C# 377
workaxis deletion 295
workaxis direction 294, 435
workaxis direction programatically 373
workaxis from a hole C# 374
workAxis in an assembly 385
WorkAxis in an assembly programatically 114
WorkAxis index C# 385
WorkAxis perpendicular to sketch point, how to 442
WorkAxis programatically Autodesk InventorProgramming in C++ 170
workaxis removal 295
workaxis visibility 253
WorkAxis, grounded programatically, in an assembly 114
WorkAxisProxy collection 294
WorkAxisProxy coordinates 294
WorkAxisProxy geometry 294
WorkAxisProxy Line 294
WorkFeatures and iParts in Autodesk InventorProgramming 188
WorkFeatures, what type is this one? ( in AutodeskInventor Programming) 194
WorkPlane and FlipNormal and constraints 485
workplane and sketch 515
WorkPlane by name C# 397
workplane from 3 points 515
workplane in an assembly programatically (AddFixed) 445
workplane inclination 494
workplane indices (standard) Inventor programming 265
workplane offset 475
workplane offset editing 456
workplane on surface of tube at an angle 501
WorkPlane orientation in C# 381
workplane positioning 475
workplane visibility 253
workplane, adding programatically, Inventor. 251
WorkPlane, getting the 3 standard ones, a functionfor 82
workplane, name of ,getting 46
WorkPlane, WorkPoint, WorkAxis and iParts 188
WorkPlaneProxy in Autodesk Inventor Programming 163
workplanes (default) 515
Workplanes and sketches programatically 265
workplanes in parallel 475
workplanes, parts, assemblies, occurrences,programatically 207
Index 549
(C) 2021 Owen F Ransen
workpoint "Center Point" getting hold of itprogramatically 112
WorkPoint at intersection between plane and line 113
WorkPoint by name 231
workpoint creation in Autodesk Inventor C++Programming 268
workpoint from sketch point 268
WorkPoint in center of a hole 517
WorkPoint into an assembly manually 112
WorkPoint into an assembly programatically 112
workpoint making 268
WorkPoint name settings 112
workpoint visibility 213, 253
WorkPoint WorkPlane WorkAxis, which is it? 194
Workspace project file 210
WorkThing by name C# 397
WorkThings in assemblies (cf parts) 440
WorlkPlane by name 231
wprintf BSTR 272
WriteLine and Trace and iLogic 31
- X -X Axis programatically 231
X Axis programatically by index 170
x64 302
XAxis of a workplane C# 381
XCount and YCount of patterns 197
XCount of a rectangular array 230
XData in Inventor programming in Autodesk InventorProgramming in C++ 238
Xrefs as Occurences and AutoDesk InventorProgramming in C++ 272
xy plane 467
XYPlane gikXIndex 265
XYPlane gikZIndex 265
XZPlane gikYIndex, 265
- Y -Y Axis programatically 231
Y Axis programatically by index 170
YAxis of a workplane C# 381
YCount of a rectangular array 230
Yellow Dot Green Dot Constraints 518
yellow rectange in an axis constraint 461
yz plane 467
YZ Plane in Autodesk Inventor C++ Programming 251
- Z -Z Axis programatically 231
Z Axis programatically by index 170
Z Axis rotation 185
Zero point 112
Zoom 46