PixelCompare with right calibration - autodesk-forge

Use Case: There are several as-built plans as PDF files. The PDF files represent different planning states.
Plan A - as-built plan first floor from 1950 on paper size Letter
Plan B - as-built first floor plan from 1999 on paper size DIN A2
Both plans are scaled to maximum paper width.
Is there a possibility to calibrate the PDF files within the Autodesk Forge Viewer to overlay the files in the correct scaling?

You have access to the source code of not only the Viewer but the extensions as well:
https://developer.api.autodesk.com/modelderivative/v2/viewers/7.*/extensions/PixelCompare/PixelCompare.js
Looking in it I did not find a way to specify how the model/sheet should be transformed. However, I found that the tool it's creating is activated after the initialization is done, which includes changing the placementTransform of the secondary sheet in order to adjust the scaling. So I can listen to the Autodesk.Viewing.TOOL_CHANGE_EVENT event and adjust the scaling of the sheet:
var pcExt = await viewer.loadExtension("Autodesk.Viewing.PixelCompare");
let onToolChange = event => {
let tr = model2.getPlacementTransform();
// double scale along X axis
tr.elements[0] *= 2;
model2.setPlacementTransform(tr);
viewer.removeEventListener(Autodesk.Viewing.TOOL_CHANGE_EVENT, onToolChange);
}
viewer.addEventListener(Autodesk.Viewing.TOOL_CHANGE_EVENT, onToolChange);
pcExt.compareTwoModels(model1, model2);
This blog post might also be useful:
https://forge.autodesk.com/blog/rotate-sheets-viewer

Related

Set Custom Viewpoint for Forge Model for a 360 kind-of centre location viewpoint

Referring to this article, the viewpoints from a model derivative URL manifest can be obtained. But I want to create a custom viewpoint in the model since I don't have those viewpoints. My requirement is below:
I would like to create a viewpoint such that it is centered at a point(aka the pivot) and I should be able to look around that point in all 360 degrees, while staying at that same point (and preventing the user from moving around the model freely if possible). I have the x,y,z viewpoint.
How can I create the aforementioned viewpoint?
How do I create an upward vector?
How do I get aspect, fov and orthoScale?
Also, I need to rotate the camera view based on event from another component. That component provides me data such as pitch, yaw and roll. How can I use that to change the camera view using the viewer.setView() method? Or is there any other method that needs to be used for changing the view with former parameters?
Details:
I have a nwd file loaded in the forge viewer.
I have the offset information available, if that plays a role in the above requirement.
Regarding the up vector, you can get that via viewer.avigation.getCameraUpVector()
For aspect, fov, and orthoScale, it's similar:
const aspect = viewer.navigation.getCamera().aspect;
cosnt fov = viewer.navigation.getVerticalFov();
const orthoScale = viewer.navigation.getCamera().orthoScale; //!<<< for Orthographic camera mode only

Viewport Data on Revit File Exists but Could Not Be Found

I am trying to use the Viewports Extension to retrieve a 3D-To-2D Matrix. This is the code I am using on my model:
viewer.loadDocumentNode(doc, sheet);
...
let viewports = viewportExt.getViewports(viewer.model);
The issue is that viewports will always be an empty array me despite checking the file in Revit and seeing that there are viewports in the sheet. I also tried checking the AECModelData that the Viewports Extension uses, and I found:
viewports: [
...
{
...
modelToSheetTransform: Array(12),
sheetGuid: <Sheet Guid>,
viewGuid: <View Guid>,
viewType: "FloorPlan",
viewportGuid: <Viewport Guid>,
viewportPosition: Array(6),
viewportRotation: 0
}
]
I checked the sheet and viewport GUIDs in Revit, and they corresponded to the AECModelData.
Unfortunately, it's hard to tell with limited information.
To make the Autodesk.AEC.ViewportsExtension work, you need to ensure that your Floor plans fit the below conditions (see here for details):
Only support 2D sheets with floor plan views, structural plan views, or reflected ceiling plan views. Other sheets with callout or area plan views are not supported currently.
Sheets with the Crop View checkbox enabled in Revit.
Views without view breaks. Views containing view breaks or view splits are not supported currently.
Here is an example of my working viewport data

Google Slides - central master template

Does anyone know of a way to have a central master template for google slide presentations that automatically cascades changes down to presentations using it ?
If not automatic then maybe there is something that can be done with google apps script to pull any changes to the master template down to the associated presentations ?
Here is a simple example of what I am trying to do:
Create master template/theme (M1) with layout (L1) with two placeholders and a company logo
Create new presentation (P1) importing theme M1 above using Layout L1
Amend master theme M1 Layout A with new company logo or new placeholder
How do i get this change to propagate to P1 without manually importing the template/theme again ? It would be ideal if P1 could subscribe to changes in M1 but i can't see any option for this so was wondering if I could script something ?
Thanks in advance
Greg
This is not possible in Apps Script right now
There is a feature request for this in the Issue Tracker, go give it a ☆!
https://issuetracker.google.com/issues/129457735
Maybe go and explain your use case for it too.
Possible avenue for workaround
The best workaround I can think of is something along the lines of this script:
function copyStyling() {
// This is a standalone script
let masterID = "1107dQEIAbZ8ipBi0wvU6cdy4OV7N2hURT5fjgOwm_vY";
let childID = "1XvGARRBzXofsjrFJkl8SCmt3tQJ2nkw1n9MG3tr9fhU";
// Master Slide Variables
let masterPresentation = SlidesApp.openById(masterID);
let masterSlide = masterPresentation.getSlides()[0];
let masterElements = masterSlide.getPageElements();
// Get style elements
let masterBackground = masterSlide.getBackground();
let masterSolidFill = masterBackground.getSolidFill().getColor();
// etc
// ...
// Child Slide Variables
let childPresentation = SlidesApp.openById(childID);
let childSlide = childPresentation.getSlides()[0];
let childElements = childSlide.getPageElements();
// Updating the stylings for the page
let childBackground = childSlide.getBackground();
childBackground.setSolidFill(masterSolidFill);
// etc
// ...
// Updating the stylings for each element on the page
masterElements.forEach((element, i) => {
childElements[i].setLeft(element.getLeft());
childElements[i].setTop(element.getTop());
// etc
// ...
});
}
This script works if both Master and Child presentations use the same theme (i.e. the master style sheets)
It works by having a single slide in a "Master presentation" which you modify and the Child presentations also have only a single slide.
It gets style info. This script gets the background of the slide (if its a solid fill) and the top left position of each element.
It then updates the child with this information.
It really depends on how many changes are going to happen to the child presentations. If no elements are going to change, and only limited style characteristics are going to change, then it shouldn't take too long to get a working script together. It would just involve going through the documentation and picking out the attributes you want to update.
If the number of elements are going to change, their positions going to be rearranged, with very different content from the placeholders, then it can get considerably more complex. Then it becomes a function of how many hours you can invest into it! Though hopefully this serves as a good starting point for that.
Ideally to this script would be added the width and height of each element to go along with the top and left position, their rotation, transformation, font, font color, font font style, direction, and minimal support for shapes. With these things I believe you could have quite a powerful tool.
Reference
Apps Script Slides Service

How to zoom in to fit the exact bounding box in Autodesk forge viewer

We want to zoom-in to a 2D sheet in forge-viewer to take screenshot and stitch multiple screenshot later to get better image quality.
We are facing issue to zoom-in to exact bounding box, it always is little less zoomed-in i.e. we can see portion of sheet which shouldn't be part of screenshot.
Take a case of dividing a 2D sheet in equal 4 quadrants to zoom-in and take screenshot (we can increase quadrants/sections as per the required image quality later), we use below code to zoom-in,
var max = viewer.model.getBoundingBox().max;
var min = viewer.model.getBoundingBox().min;
var Q1Min = new THREE.Vector3( min.x, min.y, 0 )
var Q1Max = new THREE.Vector3( (min.x)+(max.x)/2, (min.y)+(max.y)/2, 0 )
var Q1Box = new THREE.Box3(Q1Min, Q1Max);
viewer.navigation.fitBounds( immediate, Q1Box);
We also tried using below method, it also produces same result
viewer.impl.setViewFromViewBox(viewer.model, [Q1Min.x,Q1Min.y,Q1Max.x,Q1Max.y],'Q1',true)
Full sheet view as seen in browser.
Result after above code execution.
Required result, notice the difference in width of image. In some case height and width both become an issue.
Engineering came back and offered the same workaround - and see a live sample I just put together to zoom in programmatically here:
var direction = new THREE.Vector3();
camera.getWorldDirection( direction );
camera.position.add( direction.multiplyScalar(distance) ); //set distance move the camera forward to your needs
viewer.navigation.setView(camera.position,viewer.navigation.getTarget())
Also see here and here for code samples putting the above into practice.
They conceded that this could be a bug but didn't provide more details - will chase them up but guess they got other priorities for the moment like to maintain the newly released Viewer v7.

Windows Store App - SwapChainPanel DrawLine Performance

I am developing a Windows Store App using XAML / C#. The app also has a Windows Runtime Component, which is used for showing a Chart ouput using DirectX.
I am using SwapChainPanel approach for drawing the lines (x-axis, y-axis and waveform).
I chose this approach from the below MSDN sample (refer scenario 3 - D2DPanel)
http://code.msdn.microsoft.com/windowsapps/XAML-SwapChainPanel-00cb688b
Here is my question,
My waveform contains a huge number of data (ranging from 1,000 to 20,000 set of points). I am calling DrawLine continuously for all these points during each Render function call.
The control also provides panning and zooming but keeps the StrokeWidth constant irrespective of zoom level, hence the visible area (render target) might be much less than the lines I am drawing.
Does calling DrawLine for the area which are going to be off-screen cause performance issues?
I tried PathGeometry & GeometryRealization but I am not able to control the StrokeWidth at various zoom level.
My Render method typically resembles the below snippet. The lineThickness is controlled to be same irrespective of zoom level.
m_d2dContext->SetTransform(m_worldMatrix);
float lineThickness = 2.0f / m_zoom;
for (unsigned int i = 0; i < points->Size; i += 2)
{
double wavex1 = points->GetAt(i);
double wavey1 = points->GetAt(i + 1);
if (i != 0)
{
m_d2dContext->DrawLine(Point2F(prevX, prevY), Point2F(wavex1, wavey1), brush, lineThickness);
}
prevX = wavex1;
prevY = wavey1;
}
I'm kind of new to DirectX, but not to C++. Any thoughts?
Short answer: It probably will. It's good practice to push a clip before drawing. For instance, in your case, you'd do a call to ID2D1DeviceContext::PushAxisAlignedClip with the bounds of your drawing surface. That'll ensure no drawing calls attempt to draw outside the surface's bounds.
Long answer: Really, it depends on a handful of factors, including but not limited to what target the device context is drawing to, the display hardware, and the display driver. For instance, if you're drawing to a CPU-backed ID2D1Bitmap, it's probably fair to assume that there won't be much of a difference.
However, if you're directly drawing to some hardware-backed surface (a GPU bitmap, or a bitmap created from an IDXGISurface), it can get a little hairy. For example, consider this comment from an excellently documented MSDN sample. Here, the where the code is about to Clear an ID2D1Bitmap created from an IDXGISurface:
// The Clear call must follow and not precede the PushAxisAlignedClip call.
// Placing the Clear call before the clip is set violates the contract of the
// virtual surface image source in that the application draws outside the
// designated portion of the surface the image source hands over to it. This
// violation won't actually cause the content to spill outside the designated
// area because the image source will safeguard it. But this extra protection
// has a runtime cost associated with it, and in some drivers this cost can be
// very expensive. So the best performance strategy here is to never create a
// situation where this protection is required. Not drawing outside the appropriate
// clip does that the right way.