Revit API: Material Asset Parameters get and set - revit-api

I am trying to access via RevitAPI the data that is contained for particular asset. For instance I want to manipulate the Identity Data and get and eventually set some data for Manufacturer, Model, Cost and URL.
How can I achieve the same for the other Assets?
I am reading the Materials:
public IEnumerable<Material> GetMaterials(Document doc)
{
collector = new FilteredElementCollector(doc);
return collector.OfClass(typeof(Material)).OfType<Material>();
}
And then the Parameters:
public IEnumerable<Parameter> GetMaterialParameters(Material material)
{
List<Parameter> parameters = new List<Parameter>();
var localParameters = material.ParametersMap;
foreach (Parameter localParameter in localParameters)
{
parameters.Add(localParameter);
}
return parameters;
}
but still can't find where those properties are exposed.

What you really need is the Visual Materials API that was introduced in Revit 2018.1, the newest update:
Revit 2018.1 and the Visual Materials API
It is much harder and maybe impossible to achieve what you want in earlier versions.
Here are pointers to some more or less futile attempts:
Material Assets and FBX
Read Material Asset Parameter
Rendering Assets
Material Asset Textures

Finally this is how I managed to edit the parameters.
private void AssignProductData_OnClick(object sender, RoutedEventArgs e)
{
var material = (MaterialItem)MaterialsCombo.SelectedItem;
using (var transaction = new Transaction(doc))
{
transaction.Start("ChangeName");
var parameterManufacturer = material.Material.get_Parameter(BuiltInParameter.ALL_MODEL_MANUFACTURER);
parameterManufacturer.Set("Brand New Product");
var parameterCost = material.Material.get_Parameter(BuiltInParameter.ALL_MODEL_COST);
parameterCost.Set(1099.99);
var parameterModel = material.Material.get_Parameter(BuiltInParameter.ALL_MODEL_MODEL);
parameterModel.Set("R1223123KJNSDAS9089");
var parameterUrl = material.Material.get_Parameter(BuiltInParameter.ALL_MODEL_URL);
parameterUrl.Set("http://www.site.no/products/R1223123KJNSDAS9089");
transaction.Commit();
}
}

Related

How to add customDimensions and set operation_parentId for Azure function log

I created a http trigger V1 azure function on net framework 4.8, and used ILogger for logging. The code is like this.
I checked the Application Insight and queried for traces table. This table contains columns named customDimensions and operation_ParentId. May I ask is there anyway to add custom property in customDimensions column, or set a new Guid value for operation_ParentId? I know that I can use TelemetryClient sdk to create a custom telemetry client for logging. Just curious if there is any easy way which doesn't need to create a new telemetry client, because azure function offers bulit-in integration with application insight.
Also, since azure function runtimes automatically tracks requests, is there any way to change the operation_ParentId and customDimensions for requests table as well? Thanks a lot!
To get both the headers and App Insights to get the custom operation Id, two things must be overridden.
The first is an Activity that wraps the HttpClient, which is responsible for controlling the correlation headers and the other is App Insights' dependency tracing.
Although you can disable Actions completely in your HttpClients, you can just remove the one in the client by setting Activity.Current = null to limit side effects.
var operationId = "CR" + Guid.NewGuid().ToString();
var url = "https://www.microsoft.com";
using (var client = new HttpClient())
{
using (var requestMessage =
new HttpRequestMessage(HttpMethod.Get, url))
{
//Makes the headers configurable
Activity.Current = null;
//set correlation header manually
requestMessage.Headers.Add("Request-Id", operationId);
await client.SendAsync(requestMessage);
}
}
The next step is to remove the App Insights default tracking for this request. Again, you can disable dependency tracking completely, or you can filter out the default telemetry for this request. Processors are registered inside the Startup class just like initializers.
services.AddApplicationInsightsTelemetryProcessor<CustomFilter>();
public class CustomFilter : ITelemetryProcessor
{
private ITelemetryProcessor Next { get; set; }
// next will point to the next TelemetryProcessor in the chain.
public CustomFilter(ITelemetryProcessor next)
{
this.Next = next;
}
public void Process(ITelemetry item)
{
// To filter out an item, return without calling the next processor.
if (!OKtoSend(item)) { return; }
this.Next.Process(item);
}
// Example: replace with your own criteria.
private bool OKtoSend(ITelemetry item)
{
var dependency = item as DependencyTelemetry;
if (dependency == null) return true;
if (dependency.Type == "Http"
&& dependency.Data.Contains("microsoft.com")
//This key is just there to help identify the custom tracking
&& !dependency.Context.GlobalProperties.ContainsKey("keep"))
{
return false;
}
return true;
}
}
Finally, you must inject a telemetry client and call TelemetryClient.TrackDependency() in the method that makes the remote call.
var operationId = "CR" + Guid.NewGuid().ToString();
//setup telemetry client
telemetry.Context.Operation.Id = operationId;
if (!telemetry.Context.GlobalProperties.ContainsKey("keep"))
{
telemetry.Context.GlobalProperties.Add("keep", "true");
}
var startTime = DateTime.UtcNow;
var timer = System.Diagnostics.Stopwatch.StartNew();
//continue setting up context if needed
var url = "https:microsoft.com";
using (var client = new HttpClient())
{
//Makes the headers configurable
Activity.Current = null;
using (var requestMessage =
new HttpRequestMessage(HttpMethod.Get, url))
{
//Makes the headers configurable
Activity.Current = null;
//set header manually
requestMessage.Headers.Add("Request-Id", operationId);
await client.SendAsync(requestMessage);
}
}
//send custom telemetry
telemetry.TrackDependency("Http", url, "myCall", startTime, timer.Elapsed, true);
Refer here more information.
Note: The above is possible by disabling the built-in dependency tracking and App Insights and handling it on your own. But the better approach is let .NET Core & App Insights do the tracking.

Parse CLR Event with TraceProcessor

I have followed the guidance at https://learn.microsoft.com/en-us/windows/apps/trace-processing/extensibility to get my hands on the .NET Runtime events. When I get a EventContext instance with the unparsed data I have no convenient way to parse things further?
Ideally there should be a parser generator for manifest based events like it is the case with TraceEvent. Something like
TraceProcessorGen -generateEvents c:\Windows\Microsoft.NET\Framework\v4.0.30319\CLR-ETW.man
would be a big help. I am not inclinded to manually write the parsing code with hundreds of hard coded offsets for dozens of events.
class ClrDataSource : IFilteredEventConsumer
{
public IReadOnlyList<Guid> ProviderIds { get; } = new Guid[] { new Guid("e13c0d23-ccbc-4e12-931b-d9cc2eee27e4") };
public int Count { get; private set; }
public void Process(EventContext eventContext)
{
ReadOnlySpan<byte> data = eventContext.Event.Data;
// What do do next?
}
}
TraceEvent from Vance Morrison has an easy way to explore manifest based events where the Payload and PayloadNames are already preparsed based on their manifest. This is not very performant but for many cases and explorative research very helpful.
(I am a developer at Microsoft who works on the TraceProcessor project.)
IFilteredEventConsumer is a way to get at the unparsed events in the trace, and it's true that we have not added support for using a manifest file to simplify that parsing.
However, parsed events for that provider should be available in the IGenericEventDataSource like this:
using (ITraceProcessor trace = TraceProcessor.Create(tracePath))
{
Guid[] providerIds = new[] { Guid.Parse("e13c0d23-ccbc-4e12-931b-d9cc2eee27e4") };
IPendingResult<IGenericEventDataSource> pendingEventsData = trace.UseGenericEvents(providerIds);
trace.Process();
IGenericEventDataSource eventData = pendingEventsData.Result;
foreach (IGenericEvent genericEvent in eventData.Events)
{
// Process event here
}
}
Within each IGenericEvent, there is a property called Fields, which should let you access events either by integer index or by name.

How can I fetch an array of data from a custom GI using soap contract based web services

I know how to fetch data from a custom Generic Inquiry using standard soap / page-based web services.
Here's my code for standard web services to get the results from a custom GI:
static void Main(string[] args)
{
GI000081.Screen context = new GI000081.Screen();
context.Url = "http://localhost/AcumaticaDB181000062/(W(6))/Soap/GI000081.asmx";
context.CookieContainer = new System.Net.CookieContainer();
LoginResult loginResult = context.Login("admin", "Passw0rd");
if (loginResult.Code != ErrorCode.OK)
{
throw new Exception(loginResult.Message);
}
GI000081.Content GI000081Content;
GI000081Content = context.GetSchema(); //.IN202500GetSchema();
//Here's the code to obtain the GI data:
string[][] GI000081Data = context.Export
(new Command[] {
GI000081Content.Result.AccountID,
GI000081Content.Result.Address,
GI000081Content.Result.CustomerID,
GI000081Content.Result.AccountName
},
null, //This is the filter - none here, so null..
0,
false,
false
);
}
My request is, can I get an example of C# code for how to do this using the Contract-based web services. I know how to extend the endpoint and get the wsdl file / service reference to my custom Generic Inquiry, but I don't know the syntax to make the actual call.
Thanks in advance...
Just to make sure that you create the entity in the endpoint properly, make sure that the top level entity contain only the Parameters and that it has a sub entity of type details contain all the results. If there is no parameter then it is fine for the top level entity to be empty.
Here is the code sample that I used
class Program
{
static void Main(string[] args)
{
DefaultSoapClient client = new DefaultSoapClient();
client.Login("admin", "admin", null, null, null);
try
{
BatchPaymentsInq batch = new BatchPaymentsInq
{
Result = new BatchPaymentsInqResult[]
{
new BatchPaymentsInqResult { ReturnBehavior = ReturnBehavior.All }
}
};
var result = client.Get(batch);
}
catch(Exception ex)
{
}
finally
{
client.Logout();
}
}
}
Edit:
Here is how I extended my endpoint in order to use it with the Contract Based SOAP API
So the main entity named BatchPaymentsInq is pointing to the Generic Inquiry screen and will not have any field in it as you have mentioned that there is no parameter.
The sub entity Result is an array of BatchPaymentsInqResult an object created for containing the fields in the result grid of the inquiry.

Implementation of the MvxBindableCollectionViewSource

I'm new to Mvvmcross framework and currently exploring the iOS part of it (ohh and also new to iOS development to draw a beautiful picture of my current situation ^^). I'm using the vNext version.
I've found references to implementation of UICollectionViewController (MvxTouchCollectionViewController and MvxBindableCollectionViewSource), but these classes seem to be only a skeleton for a future implementation (abstract class, missing a kind of MvxSimpleBindableCollectionViewSource at least). I haven't found a sample using this feature.
I've also found a blog post from Stuart which lets presume he's working on this part (Work In Progress - MvvmCross lists sample).
Does anybody already play with this part and know about an implementation or usage example?
I've took a look to the 10 first minutes of the xaminar mentioned by Stuart in its article and seems pretty interesting, a good starting point for me.
I've used the collection view controller in several customer apps, but don't think I've published any open source samples that use it.
In essence, the use of the collectionview is very similar to the use of the tableview and cell - which is shown in detail in: http://slodge.blogspot.co.uk/2013/01/uitableviewcell-using-xib-editor.html
In vNext, a sample controller might look like:
public class MyCollectionView : BaseCollectionView<MyCollectionViewModel>
{
private bool _needToCallViewDidLoadManually;
public HubView (MvxShowViewModelRequest request)
: base(request, new UICollectionViewFlowLayout (){
ItemSize= new System.Drawing.SizeF (100, 100),
MinimumInteritemSpacing = 20.0f,
SectionInset = new UIEdgeInsets (10,50,20,50),
ScrollDirection = UICollectionViewScrollDirection.Vertical,
})
{
if (_needToCallViewDidLoadManually) {
ViewDidLoad();
}
}
public override void ViewDidLoad ()
{
if (ShowRequest == null) {
_needToCallViewDidLoadManually = true;
return;
}
base.ViewDidLoad ();
_needToCallViewDidLoadManually = false;
var source = new CollectionViewSource(CollectionView);
this.AddBindings(
new Dictionary<object, string>()
{
{ source, "ItemsSource TheItems" }
});
CollectionView.Source = source;
CollectionView.ReloadData();
}
public class CollectionViewSource : MvxBindableCollectionViewSource
{
public CollectionViewSource (UICollectionView collectionView)
: base(collectionView, MyViewCell.Identifier)
{
collectionView.RegisterNibForCell(UINib.FromName(MyViewCell.Identifier, NSBundle.MainBundle), MyViewCell.Identifier);
}
}
}
If you are starting development now, then you might also benefit from considering the v3 branch which is just entering Beta.

AsyncCallback with completed event

I am Creating a library using Facebook C# SDK for windows phone.Facebook SDK Library version is 6.0.10.0. Facebook C# SDK contains asynchronous function calls only.
In which there is a postCompleted event handler which takes object and FacebookApiEventArgs as arguments and return type is void.
I am using two classes one is UI class and other is Businesslogic class. from UI i want to call the BusinessLogic class(s) PostWall function which will simply return the last message id.
I want to create a function something like this
public string PostWall(string accessToken, string message)
{
var fb = new FacebookClient(accessToken);
fb.PostCompleted += (o, args) =>
{
if (args.Error != null)
{
return;
}
var result = (IDictionary<string, object>)args.GetResultData();
_lastMessageId = (string)result["id"];
};
var parameters = new Dictionary<string, object>();
parameters["message"] = message;
fb.PostAsync("me/feed", parameters);
}
I do not know how to implement this. Is this functionality achievable or not.
Any help appreciated
Thanks in Advance
you can check out the wp7 sample at at https://github.com/facebook-csharp-sdk/facebook-windows-phone-sample.
What you are doing is already correct.

Resources