Customizing Drawing tool in Autodesk Forge Viewer throws error - autodesk-forge

I am using the Autodesk Forge Viewer API to render the AutoCAD drawing files on the web page. It is working perfectly.
Then I followed the below tutorial to provide markup/annotation support on the viewer.
https://developer.api.autodesk.com/viewingservice/v1/viewers/docs/tutorial-feature_markup.html
Though I am able to get different drawing tools to work as expected, the customizing the color of the markup is throwing an error.
vm.onColorChange = function (e) {
var styleAttributes = ['stroke-color'];
var nsu = Autodesk.Viewing.Extensions.Markups.Core.Utils;
var styleObject = nsu.createStyle(styleAttributes, vm.markupsExtension.viewer);
var selectedColor = $('#sel-colors').val();
styleObject['stroke-color'] = selectedColor;
vm.markupsExtension.setStyle(styleObject);
};
When I debugged the code on the developer tool, the below line in the 'Markups.js' is throwing the error 'getStrokeWidth' is undefined.
I am using the Forge viewer version 6. Is there anything changed for customizing the drawing tool with the latest version of the viewer or is the tutorial still relevant for the current version.

The second argument to pass in to Markups.Core.Utils.createStyle should be the current active Markup tool object, not the Viewer itself:
var markupExt = Viewer.getExtension("Autodesk.Viewing.Markups ore");
var styleObj = Autodesk.Viewing.Extensions.Markups.Core.Utils.createStyle([...], markupExt)
That bit of the tutorial is incorrect and will be rectified soon.

Related

How to view local drawing DWF file with correct font?

I am trying to view local dwf files in browser using forge viewer.
I followed this: https://aps.autodesk.com/blog/dwf-and-pdf-support-forge-viewer
example to load local dwf file into the viewer.
let option = { env: "Local" };
Autodesk.Viewing.Initializer(option, async function () {
const viewer = new Autodesk.Viewing.GuiViewer3D(document.getElementById('forgeViewer'));
viewer.start();
viewer.setTheme('dark-theme');
viewer.loadExtension('Autodesk.DWF').then(() => {
console.log("Extension Loaded")
console.log(path);
try {
viewer.loadModel(virtualPath + path);
} catch (e) {
console.log(e)
alert("Nepodařilo se načíst požadovaný soubor!")
}
});
});
But there is a problem with font:
forge-viewer-result
When I view the same file with "Autodesk Design Review" the font is correct:
design-review-result
Detailed problems I have in my implementation of Forge Viewer:
It is not the correct ISOCPEUR and it does not support characters with diacritics.
Also it uses blue background and looks different compared to other Autodesk viewing apps I have seen. (Vault Thin Client, DR)
The image (company logo) is blurred
Am I missing some sort of setting to the viewer?
I don't think you're missing any settings. The native DWF loading in JavaScript is a relatively new feature, and there may be areas that require some polishing. If you wouldn't mind sharing one of the DWFs with us (confidentially via forge (dot) help (at) autodesk (dot) com; the file would not be shared with anyone outside of Autodesk), we can ask the viewer engineering team to look at it.
In the meantime, have you tried converting the DWF into the viewer format using the Model Derivative service? While this operation has some cost (0.1 flex tokens per DWF), it uses AutoCAD to process the DWF, so it is generally more robust.

Load model by headless viewer

I have tried setting up Forge Viewer in headless mode using the following link: https://forge.autodesk.com/en/docs/viewer/v6/tutorials/headless.
I have hard-coded the URN and the access token but the model is not displaying.
Please provide any sample source code to load the model.
Here's a couple of tips:
Check the browser console. Perhaps the URN or the access token is incorrect, which is why the model does not load.
The link you're working with is for an older version of Forge Viewer (v6). I'd suggest using version 7.*. Try using this basic app as a starting point: https://github.com/petrbroz/forge-basic-app, and replace this line of code:
const viewer = new Autodesk.Viewing.GuiViewer3D(document.getElementById('preview'));
with
const viewer = new Autodesk.Viewing.Viewer3D(document.getElementById('preview'));
With this I've been able to load a model with a headless viewer:

Plot to PDF Differences between Forge AutoCAD and AutoCAD Desktop

I am currently trying to standardize some cleaning and plot functions on Autodesk Forge. My development process is to write my Design Automation plugins in Visual Studio, test in Autocad Desktop (Windows) via the NETLOAD command, and then push to forge.
However, I am noticing huge differences between the output in Forge and the Output in AutoCAD.
First, in forge my plot gets created with black rectangle borders for some reason. The centering is also very different in Forge even though I am taking steps in my script to set it.
Here is the printing part of my script:
using (Transaction tr = db.TransactionManager.StartTransaction())
{
BlockTableRecord btr = (BlockTableRecord)tr.GetObject(
db.CurrentSpaceId,
OpenMode.ForRead, false, true
);
Layout lo = (Layout)tr.GetObject(
btr.LayoutId,
OpenMode.ForRead, false, true
);
PlotInfo pi = new PlotInfo();
pi.Layout = btr.LayoutId;
PlotSettings ps = new PlotSettings(lo.ModelType);
ps.CopyFrom(lo);
PlotSettingsValidator psv = PlotSettingsValidator.Current;
psv.SetPlotType(
ps,
Autodesk.AutoCAD.DatabaseServices.PlotType.Extents
);
psv.SetUseStandardScale(ps, true);
psv.SetStdScaleType(ps, StdScaleType.ScaleToFit);
psv.SetPlotCentered(ps, true);
psv.SetPlotConfigurationName(
ps,
"DWG To PDF.pc3",
"ANSI_A_(8.50_x_11.00_Inches)"
);
pi.OverrideSettings = ps;
PlotInfoValidator piv = new PlotInfoValidator();
piv.MediaMatchingPolicy =
MatchingPolicy.MatchEnabled;
piv.Validate(pi);
}
Here's an example difference between Forge and AutoCAD Desktop with the exact same script:
AutoCAD Desktop (this is what its intended to look like):
AutoCAD Desktop
Forge Output:
Forge

Is it possible to load new Cloud (BIM 360) links in a Revit model either through the Revit API or FORGE API?

I have a two-part WPF App and Revit Addin that runs a series of routines to create and activate a new BIM 360 project via the FORGE BIM 360 API, launches Revit and creates and sets up a collection of Revit models from a "seed" Revit model. The primary requirement is to have zero user interaction in this process: to be fully automated.
Given that background, I am having trouble linking the newly saved BIM 360 models to one-another. I have the option to do this either in the Revit Addin with Revit API hooks (preferred) or through the manager WPF App with FORGE API REST calls after the models are created.
Is either one possible?
I have successfully linked with the cached local models as described here and here. However, this does not meet the requirement fully, since when any other user (besides the automation machine user) opens the model the links are Not Found.
Screenshot of links Not Found.
Current "sort-of-working" code:
var wId = GetWorksetId(doc, w);
if (wId != null)
{
string localPath = settings.CloudModels.Where(x => x.ModelName == _linkModelNames[i]).Select(x => x.LocalFilePath).First();
ModelPath path = ModelPathUtils.ConvertUserVisiblePathToModelPath(localPath);
using (var options = new RevitLinkOptions(true))
{
using (var t = new Transaction(doc, w))
{
t.Start();
doc.GetWorksetTable().SetActiveWorksetId(wId);
using (var result = RevitLinkType.Create(doc, path, options))
{
_ = RevitLinkInstance.Create(doc, result.ElementId);
}
t.Commit();
linkPlaced++;
}
}
}
I was able to get the correct ModelPath via the Revit API thanks to this helpful tip. I can save this value in my Addin, close the model, and access the property later after opening a different model (saved in the CloudModels class referenced in the linq statement in the code snippet above). Unfortunately for me RevitLinkType.Create() that takes a ModelPath does not accept the cloud path, so I may have hit another dead end. Unless it is possible with an ExternalResourceReference. Has anyone tried this option? If so, how do you assemble a Revit ExternalResourceReference? I am not familiar with this process, and looking over this course from AU 2017, I don't see that it necessarily applies to BIM 360 cloud models. A BIM 360 cloud example would be very helpful if this is possible.
Alternate strategy: I do not see any reference to loading links in the FORGE Data Management API or other FORGE APIs. If I have somehow missed it, please share a link.
Any help would be very much appreciated!!
EDIT: I have since found these two (1) (2) similar questions that, at least for my purposes, were not answered satisfactorily. Any updates I should be aware of?
As of now (Jan 2020), unfortunately, we do not have a Link API for cloud models. It is on the roadmap.
Revit API 2022 docs mention that
The methods:
RevitLinkType.Create(Document, ModelPath, RevitLinkOptions)
RevitLinkType.LoadFrom(ModelPath, WorksetConfiguration)
have been enhanced to support creation of new cloud model Revit links.
You may use ModelPathUtils.ConvertCloudGUIDsToCloudPath() to
create a cloud path to use as an argument to these methods.
Additional Resource:
This Youtube Video showcases an example and its respective Github repo.
For Revit 2021 and below, you can use ExternalResourceReference() as a workaround, but I've noticed that this is not always reliable.
Its also mentioned in the documentation of InSessionPath property to not rely on this property:
Do not rely on this path (InSessionPath ) to look up an ExternalResourceReference, as the path is neither unique nor stable. It isn't unique because multiple servers might use the same server name and display name format. It isn't stable because some servers allow renaming, and because a server might change its name at some point.
Below is the code to do that:
var linkCloudPath = doc.GetCloudModelPath(); // the cloudpath of a BIM360 model
Guid linkedmodelguid = linkCloudPath.GetModelGUID();
Guid linkedprojectguid = linkCloudPath.GetProjectGUID();
Dictionary<string, string> Dictionary_ExternalResource = new Dictionary<string, string>(){
{"LinkedModelModelId", modelGuid.ToString()},
{"LinkedModelProjectId", projGuid.ToString()}
};
Dictionary<string, Guid> servers = new Dictionary<string, Guid>();
foreach (var service in ExternalServiceRegistry.GetServices())
{
if (service.Name == "External Resource Service")
{
IList<Guid> server_ids = service.GetRegisteredServerIds();
foreach (var server_id in server_ids)
{
servers.Add(service.GetServer(server_id).GetName(), server_id);
}
}
}
Guid BIM360ServerID = servers["BIM 360"];
ExternalResourceReference ERS = new ExternalResourceReference(BIM360ServerID, Dictionary_ExternalResource, "", "");
RevitLinkOptions options = new RevitLinkOptions(false);
LinkLoadResult result = RevitLinkType.Create(gcdoc, ERS, options);
RevitLinkInstance.Create(gcdoc, result.ElementId);
Please note that this seems to be working fine in Revit 2020, but not in Revit 2021.
I believe it is possible to create links to the Cloud Models in Revit 2019 or higher (with ModelPathUtils.ConvertCloudGUIDsToCloudPath()). You'll need the ProjectGUID and ModelGUID to make the cloud model path.
Regarding the ExternalResource approach, that also works - but it's super messy - you can read the properties associated with existing BIM360 links and you'll see how an ExternalResource is defined for BIM360 links.
Finally - as of today, the Forge Design Automation for Revit approach would not work for you at all:
1. Not possible to open a live cloud workshared model (only published/uploaded models).
2. No network access while you're running in a Design Automation for Revit session.
Good luck...
-Matt

Google Apps PivotCharts not working?

I'm trying to use the PivotCharts library that is recommended in on the apps developer site here: https://developers.google.com/apps-script/notable-script-libraries - but when I try replicating the example code:
function createReport(){
var app = UiApp.createApplication().setWidth(700).setHeight(450).setTitle('My report');
var data = SpreadsheetApp.openById('0AnxR7WfXrj7adFRnVEFTQ2NldGJodUtCZDF2U0hVNUE').getSheets() [0].getDataRange().getValues();
var panel = PivotChartsLib.createColumnChart(data, 3, 4);
app.add(panel);
SpreadsheetApp.getActiveSpreadsheet().show(app);
}
The initial chart loads, but when you try to pivot you get an error "Type Error: can not call method "apply" of undefined"
I've tested on different computers, so I think it is an issue with the library itself. I'm not sure how to access that code though to try and fix it.
I saw same error.
then i copied code from PivotCarts library,
it worked fine.
it seems pivot charts library ui need apply function,
that should be global scope function , but PivotCharts's apply function scope is into PivotCharts object.