How can I run built-in Revit commands from C# - c#

I am wanting to know if there is a methodology to feed calculated values to a built-in Revit command from inside a C# program, and then possibly (based on results, such as whether this makes an element too short or too long for a known "maximum span" of a particular beam) continue with my C# program and change the beam size). I am told you can invoke the Revit built-in command after execution of your c# external command, but you cannot then return to the c# program
As another example, I want to select an element to trim/extend to, and have the code figure out which "Joist" beams to extend to this element. My program would do extended filtering (such as "Reference Level", or "Workset", or "Comments", or "Mark" parameters (etc.)) and then run the built in function, providing the element to extend to and then each of my beams.
I've tried internet searches, as well as the Revit SDK samples, and nothing obviously used this (but there are a lot of csproj's to look through).
Can anyone verify that you cannot go back and forth between the C# program and the Revit built-in command?

You can programmatically invoke a built in Revit command with the UIApplication.PostCommand() method. Refer to documentation and building coder for more information. It will not execute until after the API context is over, however.
I don't think you'll be able to feed arguments into the command however, short of some kind of Win32 hack. Perhaps you will need to recreate the functionality of the built in command within the Revit API.
Unfortunately, I don't think we can do (command "_line" pnt1 pnt2) type of thing here.

Perhaps start with the SDK sample "MoveLinear". It shows how to modify end points of linear elements (which includes beams).
The main part of the sample's code is
Autodesk.Revit.DB.Line line;
//get start point via "get_EndPoint(0)"
Autodesk.Revit.DB.XYZ newStart = new XYZ(
lineLoc.Curve.GetEndPoint(0).X + 100,
lineLoc.Curve.GetEndPoint(0).Y,
lineLoc.Curve.GetEndPoint(0).Z);
//get end point via "get_EndPoint(1)"
Autodesk.Revit.DB.XYZ newEnd = new XYZ(
lineLoc.Curve.GetEndPoint(1).X,
lineLoc.Curve.GetEndPoint(1).Y + 100,
lineLoc.Curve.GetEndPoint(1).Z);
//get a new line and use it to move current element
//with property "Autodesk.Revit.DB.LocationCurve.Curve"
line = Line.CreateBound(newStart, newEnd);
lineLoc.Curve = line;
Which moves the X of the first point and the Y of the second point 100 feet.

you can try:
RevitCommandId commandId = RevitCommandId.LookupPostableCommandId(PostableCommand.PlaceAComponent);
commandData.Application.PostCommand(commandId);

Related

POS for .NET line breaks

I am using "PosPrinter" .NET class to print receipts to POS Printer. Everything seems to be working fine except the line breaks. When I pass in a long string it does automatically breaks the long line into more than 1 line but it actually breaks WITHIN the word.
So, I need a way to break the word instead of breaking within the word. I appreciate your help. T
Code
m_Printer.PrintNormal(PrinterStation.Receipt, "\u001b|N华夷风起 : 华夷风起:槟城文史研习营 = When the wind of the Sinophone blows: Penang seminar 2019.\n");
There is no such specification in POS for.NET(UnifiedPOS).
If that is the case, it may be a special feature of particular printer hardware or service object.
Please ask the printer vendor about the availability of such a function and ON/OFF.
If more information about the printer vendor and model is added, someone may be able to answer.
However, since there is probably no such function, you will need to read the value of the RecLineChars property and edit the content to be printed in advance by the application itself.

Excel-DNA: grouping rows via C API feature of Excel-DNA

I'm familiar with how to group a range in Excel VSTO/COM interop:
ws.EnableOutlining = true;
ws.Outline.SummaryRow = XlSummaryRow.xlSummaryAbove;
var rng = GetRangeSomeHow();
rng.EntireRow.Group();
rng.EntireRow.OutlineLevel = someLevel;
What is the most efficient way to do this in Excel-DNA? I would imagine there must be a C-API way to do it, encapsulated cleverly in Excel-DNA somehow, but for the life of me, I can't figure it out via online documentation (incl. Google).
There's a lot of posts using code similar to my sample above, but these are pretty expensive calls, especially since I need to do this ~5000 times overall (I have a really big data set).
EDIT:
So there seems to be this method call:
XlCall.Excel(XlCall.xlfGroup...)
The only problem is, I have no idea what the parameters are. It seems an ExcelReference should be passed in, but how is the .EntireRow resolved? Will the C API just handle it for me - in which case I just need to pass a new ExcelReference(1,100,1,1) and be done with it... or is there more to this?
Thanks in advance to anyone who can answer my question!
I don't think the C API GROUP function is te one you're looking for. The documentation says:
GROUP
Creates a single object from several selected objects and returns the
object identifier of the group (for example, "Group 5"). Use GROUP to
combine a number of objects so that you can move or resize them
together.
If no object is selected, only one object is selected, or a group is
already selected, GROUP returns the #VALUE! error value and interrupts
the macro.
I'd suggest you use the COM object model for this kind of thing, even in an Excel-DNA add-in. The C API has not really been updated over the years for the general sheet manipulation like this case, so you're likely to run into some features that don't work right or are incomplete relative to the COM object model.
From your Excel-DNA add-in, just make sure your get hold of the right Application root object with a call to ExcelDnaUtil.Application.
For improved performance of this kind of sheet editing, you pretty much have to use the same tricks as from VBA or VSTO - disable screen updating and calculations etc.

Calling NvAPI_GPU_SetEDID on Nvidia card

How do you call this method on Nvidia GPU:
NVAPI_INTERFACE NvAPI_GPU_SetEDID (
NvPhysicalGpuHandle hPhysicalGpu,
NvU32 displayOutputId,
NV_EDID * pEDID
)
Src: http://docs.nvidia.com/gameworks/content/gameworkslibrary/coresdk/nvapi/group__gpu.html#ga6a41b31dd9743120213435d985f8fbcf
I need to execute the above command to remove all EDID set on all DisplayOutputs on our new Quadro Graphics Cards. Based on the API documentation, I tried searching for NvPhysicalGpuHandle and came across this project/library:
https://github.com/openhardwaremonitor/openhardwaremonitor/blob/master/Hardware/Nvidia/NVAPI.cs
This does not have the method I need NvAPI_GPU_SetEDID
I am not hardware programmer, I just need to be able to call this one command. any ideas? Can this be achieved using nvapi.dll/nvapi64.dll via pinvoke or something?
I personally didn't test this, but you can try the library and see if it can set EDID information without any problem, if it fails, please open an issue.
https://github.com/falahati/NvAPIWrapper
Here is how you should do it,
First, you need to find the right DisplayDevice or GPUOutput that you want to write EDID information to. There are multiple ways to do so.
Get a list of all PhysicalGPUs in the system using the NvAPIWrapper.GPU.PhysicalGPU.GetPhysicalGPUs() static method, then select the PhysicalGPU you desire based on your logic. After finding the right PhysicalGPU, use the NvAPIWrapper.GPU.PhysicalGPU.GetDisplayDevices() method to get a list of all connected DisplayDevices to that GPU and store the right one in a variable.
Instead of searching for connected DisplayDevices, you can also go for the GPUOutputs. Just like before, you first need to find the right PhysicalGPU and then you can get a list of all GPUOutputs using the NvAPIWrapper.GPU.PhysicalGPU.ActiveOutputs property and store the right GPUOutput in a variable.
Another way to find the right DisplayDevice is to go for a list of all Displays. To do so, you need to use the NvAPIWrapper.Display.Display.GetDisplays() static method. This returns an array of Displays. Then using the NvAPIWrapper.Display.Display.DisplayDevice property, you can get the corresponding DisplayDevice of a Display.
After finding the right DisplayDevice or GPUOutput, you should use the NvAPIWrapper.GPU.PhysicalGPU.WriteEDIDData() method. This method allows you to write EDID data stored in a byte array to the DisplayDevice or the GPUOutput you selected before.
Note: Make sure to capture NVIDIAApiException and check for the NVIDIAApiException.Status property in case something went wrong.

Issue with printing an arbitrary sequence of strings and images in C#

So, long story short: I'm writing a POS program, and I have a receipt printer connected and the Windows Forms printing API works great with it, much easier than I expected.
However, searching through the API, it seems that the easiest (or perhaps only) way to programmatically print something is to use the Graphics object inside the PrintPageEventArgs object in the printer's event handling method.
Every overloaded parameter list for the Graphics.DrawXXX() method requires some kind of coordinate pair to use as a reference point for where to start drawing the object passed to it.
So my question is, let's say I want to print some string value, and then an Image. Doing it the other way around (first the Image, then the string) would be easy because the reference point to start drawing the string would be (0, Image.Size.Height). However, since a string does not have a "size" associated with it, what is the best way to go about telling the printer where to start drawing an image after a string has been printed?
Let me know if this is confusing or needs additional clarification.

Is there a way to create programmatically something similar to the Visual Studio 'Go To Implementation' functionality?

I'm looking for a way to read the contents of a method/function call, something similar to the Visual Studio 'Go To Implementation' functionality (or F11 in debug) but using code.
For example, if I had a C# .cs file that contained the following code:
var characters = "AAAAAABBBBBBCCCCCCDDDDDD";
var position = 0;
var newPosition;
//Example #1
myObject.FirstSixCharacters = characters.SubString(position, 6);
position += 6;
//Example #2
myObject.SecondSetOfSixCharacters = AStaticObject.AMethod(characters, position, 6, out newPosition);
position += newPosition;
I'd like to know if there is a way to programatically 'drop' into the 'AMethod' method of the 'AStaticObject' object and read the code?
To put the question into context, I have a large enterprise solution that in essence - parses a very large string of characters into lots of DTO fields. I'm thinking of writing something that will open a 'parser' .cs file, read the contents of the code then determine the position and length of each DTO field based upon the processing applied at the time of the assignment.
This is fairly straight forward to achieve for statements where the field assignment is the result of a simple 'substring' function (as per example #1, above). But on occassion the code uses static objects/methods to extract the characters of the string and update the positional variable (as per example #2, above). This led me to the question - "how can I, programmatically, read the code within the .cs file and when necessary follow calls made to objects/methods when they appear within the code and read the contents of those .cs file"?
Note: The code that I'm attempting to analyse is un-compiled, so decompiliers are not necessary to achieve the result.

Categories