Load skin from different spine's atlas - spine.js

I have 2 spine avatars: Nora & Zelly
Nora is setup as the based avatar with different animations
Zelly is setup as the skin avatar with different skins that will be added to based avatar.
Currently I have the unity runtime working:
SkeletonAnimation will automatically update the materials in LateUpdate() based on skins.
var spineBase = baseObj.GetComponent<SkeletonAnimation>();
var spineChange = switchObj.GetComponent<SkeletonAnimation>();
Spine.Skin skinDefault = spineBase.Skeleton.Data.FindSkin("all"); //Nora
Spine.Skin skinWing = spineChange.Skeleton.Data.FindSkin("wing"); //zelly
Spine.Skin skinMix = new Spine.Skin("Mix");
skinMix.CopySkin(skinDefault);
skinMix.AddSkin(skinWing);
spineBase.skeleton.SetSkin(skinMix);
spineBase.skeleton.UpdateCache();
spineBase.skeleton.SetSlotsToSetupPose();
However, it doesn't work in web runtime:
It seems like the spine runtime is not mapping the texture correctly
const newSkin = new Skin('custom-skin');
const baseSkin = basePlayer.skeleton!.data.findSkin('all');
if (baseSkin) {
newSkin.copySkin(baseSkin);
}
const wing = skinPlayer.skeleton!.data.findSkin('wing');
if (wing) {
newSkin.addSkin(wing);
}
basePlayer.skeleton!.setSkin(newSkin);
basePlayer.skeleton!.updateCache();
basePlayer.skeleton!.setSlotsToSetupPose();
basePlayer.skeleton!.setToSetupPose();
basePlayer.skeleton!.updateWorldTransform();
Thanks

Related

Forge Data Visualization not working on Revit rooms [ITA]

I followed the tutorials from the Forge Data Visualization extension documentation: https://forge.autodesk.com/en/docs/dataviz/v1/developers_guide/quickstart/ on a Revit file. I used the generateMasterViews option to translate the model and I can see the Rooms on the viewer, however I have problems coloring the surfaces of the floors: it seems that the ModelStructureInfo has no rooms.
The result of the ModelStructureInfo on the viewer.model is:
t {model: d, rooms: null}
Here is my code, I added the ITA localized versions of Rooms as 3rd parameter ("Locali"):
const dataVizExtn = await this.viewer.loadExtension("Autodesk.DataVisualization");
// Model Structure Info
let viewerDocument = this.viewer.model.getDocumentNode().getDocument();
const aecModelData = await viewerDocument.downloadAecModelData();
let levelsExt;
if (aecModelData) {
levelsExt = await viewer.loadExtension("Autodesk.AEC.LevelsExtension", {
doNotCreateUI: true
});
}
// get FloorInfo
const floorData = levelsExt.floorSelector.floorData;
const floor = floorData[2];
levelsExt.floorSelector.selectFloor(floor.index, true);
const model = this.viewer.model;
const structureInfo = new Autodesk.DataVisualization.Core.ModelStructureInfo(model);
let levelRoomsMap = await structureInfo.getLevelRoomsMap();
let rooms = levelRoomsMap.getRoomsOnLevel("2 - P2", false);
// Generates `SurfaceShadingData` after assigning each device to a room (Rooms--> Locali).
const shadingData = await structureInfo.generateSurfaceShadingData(devices, undefined, "Locali");
// Use the resulting shading data to generate heatmap from.
await dataVizExtn.setupSurfaceShading(model, shadingData, {
type: "PlanarHeatmap",
placePosition: "min",
usingSlicing: true,
});
// Register a few color stops for sensor values in range [0.0, 1.0]
const sensorType = "Temperature";
const sensorColors = [0x0000ff, 0x00ff00, 0xffff00, 0xff0000];
dataVizExtn.registerSurfaceShadingColors(sensorType, sensorColors);
// Function that provides a [0,1] value for the planar heatmap
function getSensorValue(surfaceShadingPoint, sensorType, pointData) {
const { x, y } = pointData;
const sensorValue = computeSensorValue(x, y);
return clamp(sensorValue, 0.0, 1.0);
}
const sensorType = "Temperature";
dataVizExtn.renderSurfaceShading(floor.name, sensorType, getSensorValue);
How can I solve this issue? Is there something else to do when using a different localization?
Here is a snapshot of what I get from the console:
Which viewer version you're using? There was an issue causing ModelStructureInfo cannot produce the correct LevelRoomsMap, but it gets fixed now. Please use v7.43.0 and try again. Here is the snapshot of my test:
BTW, if you see t {model: d, rooms: null} while constructing the ModelStructureInfo, it's alright, since the room data will be produced after you called ModelStructureInfo#getLevelRoomsMap or ModelStructureInfo#getRoomList.

AmCharts 4 : Can't customize (color, strokeWidth) my series

EDIT : OK, It was my css page which had a rule on path, 'cause I use svg a lot. Removed that rule and the problem was gone !
I'm facing something pretty annoying and which I do not understand.
I'm using amChart to make a XY chart with multiple series. Not that hard.
The thing is, I can't customize my series ! Bullets and legend are ok, but not series.
Here's a screenshot for better understanding :
MyWeirdChart (new OP can't embed images, sorry)
As you can see I have my custom bullet pushed on my series and my legend is exactly what I want for my chart BUT series are staying unchanged.
Here is my JS draw function :
function drawChart(dateArray, casesArray, deathsArray, healedArray, hospitalizationsArray, reanimationsArray) {
am4core.useTheme(am4themes_animated);
var chart = am4core.create("chartdiv", am4charts.XYChart);
chart.data = generateChartData(dateArray, casesArray, deathsArray, healedArray, hospitalizationsArray, reanimationsArray);
var dateAxis = chart.xAxes.push(new am4charts.DateAxis());
var valueAxis = chart.yAxes.push(new am4charts.ValueAxis());
function pushSeries(field, name, color) {
let series = chart.series.push(new am4charts.LineSeries());
series.dataFields.valueY = field;
series.dataFields.dateX = "date";
series.name = name;
series.tooltipText = name + ": [b]{valueY}[/]";
series.stroke = am4core.color(color);
series.strokeWidth = 3;
series.fill = am4core.color(color);
series.fillOpacity = 0.5;
let bullet = series.bullets.push(new am4charts.CircleBullet());
bullet.circle.stroke = am4core.color(color);
bullet.circle.strokeWidth = 2;
bullet.circle.fill = am4core.color(color);
bullet.circle.fillOpacity = 0.5;
bullet.circle.radius = 3;
}
pushSeries("cases", "Cas confirmés", "#32B3E3");
pushSeries("healed", "Guéris", "#00C750");
pushSeries("hospitalizations", "Hospitalisations", "#FFBB33");
pushSeries("reanimations", "Réanimations", "#FE3446");
pushSeries("deaths", "Morts", "black");
chart.cursor = new am4charts.XYCursor();
chart.scrollbarX = new am4core.Scrollbar();
chart.legend = new am4charts.Legend();
chart.cursor.maxTooltipDistance = 0;
}
Did I miss something ? I crawled forums and documentations and I'm now helpless.
My code is in my webpack app.js file. But I include amCharts with HTML scripts,
<script src="https://www.amcharts.com/lib/4/core.js"></script>
<script src="https://www.amcharts.com/lib/4/charts.js"></script>
<script src="https://www.amcharts.com/lib/4/themes/animated.js"></script>
not with webpack import. But I guess that if this was the problem, I would not be able to draw a chart at all.
OK, It was my css page which had a rule on path, 'cause I use svg a lot. Removed that rule and the problem was gone !

Photoshop script to duplicate and rename layer

While creating a script that would automate all the different tasks I do when I start working on a new picture on Photoshop, I encountered the following problem.
I want to create different groups and different layers inside these groups. Everything goes perfectly fine until this :
#target photoshop
app.bringToFront();
var doc = app.activeDocument;
newCurve();
var clippingHelpLayerLight = doc.activeLayer;
clippingHelpLayerLight.blendMode = BlendMode.SCREEN;
clippingHelpLayerLight.name = "Clipping Help Layer - Light";
clippingHelpLayerLight.visible = false;
clippingHelpLayerLight.duplicate();
var clippingHelpLayerLighter = doc.activeLayer;
clippingHelpLayerLighter.name = "Clipping Help Layer - Lighter";
clippingHelpLayerLighter.visible = false;
function newCurve() {
var c_ADJ_LAYER = charIDToTypeID("AdjL");
var c_ADJUSTMENT = charIDToTypeID("Adjs");
var c_CHANNEL = charIDToTypeID("Chnl");
var c_COMPOSITE = charIDToTypeID("Cmps");
var c_CURVE = charIDToTypeID("Crv ");
var c_CURVE_A = charIDToTypeID("CrvA");
var c_CURVES = charIDToTypeID("Crvs");
var c_HORIZONTAL = charIDToTypeID("Hrzn");
var c_MAKE = charIDToTypeID("Mk ");
var c_NULL = charIDToTypeID("null");
var c_POINT = charIDToTypeID("Pnt ");
var c_TYPE = charIDToTypeID("Type");
var c_USING = charIDToTypeID("Usng");
var c_VERTICAL = charIDToTypeID("Vrtc");
var d_CURVES_LAYER = new ActionDescriptor();
// Contains all the information necessary to perform the "MAKE" action
var r_CLASS = new ActionReference();
r_CLASS.putClass(c_ADJ_LAYER);
d_CURVES_LAYER.putReference(c_NULL, r_CLASS);
// Class of make action is of an ajdustment layer
var d_TYPE_CURVES = new ActionDescriptor();
// Contains all the information about all the curves
var d_CHANNEL_CURVES = new ActionDescriptor();
var l_CHANNEL_CURVES = new ActionList();
// Contains a list of channel curves
var d_CHANNEL_CURVE = new ActionDescriptor();
// Information for 1 channel curve
var r_CHANNEL = new ActionReference();
r_CHANNEL.putEnumerated(c_CHANNEL, c_CHANNEL, c_COMPOSITE);
// This curve is for the composite channel - VARIES
d_CHANNEL_CURVE.putReference(c_CHANNEL, r_CHANNEL);
// Contains the point list
var l_POINTS = new ActionList();
// List of points for this channel - LENGTH VARIES
var d_POINT = new ActionDescriptor();
// One point on the curve, has INPUT and OUTPUT value
d_POINT.putDouble(c_HORIZONTAL, 0.000000);
d_POINT.putDouble(c_VERTICAL, 0.000000);
l_POINTS.putObject(c_POINT, d_POINT);
//var d_POINT3 = new ActionDescriptor();
d_POINT.putDouble(c_HORIZONTAL, 255.000000);
d_POINT.putDouble(c_VERTICAL, 255.000000);
l_POINTS.putObject(c_POINT, d_POINT);
// Made the list of points
d_CHANNEL_CURVE.putList(c_CURVE, l_POINTS);
// Now have a list of points for a specific channel
l_CHANNEL_CURVES.putObject(c_CURVE_A, d_CHANNEL_CURVE);
// Add to the list of channel curves
d_CHANNEL_CURVES.putList(c_ADJUSTMENT, l_CHANNEL_CURVES);
// All the channel curves are inside here
d_TYPE_CURVES.putObject(c_TYPE, c_CURVES, d_CHANNEL_CURVES);
// .....
d_CURVES_LAYER.putObject(c_USING, c_ADJ_LAYER, d_TYPE_CURVES);
// package the curves and definition of the adjustment layer type
executeAction(c_MAKE, d_CURVES_LAYER, DialogModes.NO);
}
I actually want to create a first layer called "Clipping Help Layer - Light", blend mode : screen and turn it off. Then duplicate it, change the name of the new layer as "Clipping Help Layer - Lighter" and turn it off too.
Like this : Screenshot of what I would like to do
It does create the 2 layers, but the first one has " copy" at the end of its name and it stays turned on.
Screenshot of the actual result
Why ?
I can't understand why it doesn't work as expected and can't manage to fix it.
Any help would be greatly appreciated !
I believe the problem you are encountering has to do with doc.activeLayer. After you duplicate "Clipping Help Layer - Light," the script does not seem to change what doc.activeLayer is pointing to so when you then try to assign it to clippingHelpLayerLighter, you are then pointing at an undefined layer. While I don't know exactly what is happening behind the scenes when you do that, I do believe this will fix your problem:
#target photoshop
app.bringToFront();
var doc = app.documents.add( 4, 4 );
doc = app.activeDocument;
var clippingHelpLayerLight = doc.activeLayer;
clippingHelpLayerLight.blendMode = BlendMode.SCREEN;
clippingHelpLayerLight.name = "Clipping Help Layer - Light";
clippingHelpLayerLight.visible = false;
clippingHelpLayerLight.duplicate();
doc.activeLayer = doc.layers[ "Clipping Help Layer - Light copy" ];
doc.activeLayer.name = "Clipping Help Layer - Lighter";
doc.activeLayer.visible = false;
//I am not sure if you need this pointer to be called upon later in your
//code. If you do not, just leave this line out.
var clippingHelpLayerLighter = doc.activeLayer;
Hope this helps! Let me know if you have any questions, I'm by no means an expert but I use scripts fairly often.

QGroupBox sizing with my QT5 custom widget

I am trying to make a custom widget: for displaying a processor register which has a name, a value and can be displayed in octal/decimal hexa. The code is shown at the bottom. I receive better result when I use the code as shown (i.e I insert QRadioButtons):
If I use
mainLayout->addWidget(DisplayMode);
instead (I guess this is the correct method) then the resulting picture is
Do I misunderstand something? What is wrong?
RegisterWidget::RegisterWidget(QWidget *parent)
:QFrame (parent)
{
mValue = 0;
mName = "";
setFrameStyle(QFrame::Panel | QFrame::Sunken);
QHBoxLayout *mainLayout = new QHBoxLayout(this);
label = new QLabel(tr("mName"),this);
label->setText(mName);
label->setLineWidth(2);
QGroupBox *DisplayMode = new QGroupBox("");
QRadioButton *OctalR = new QRadioButton(this);
QRadioButton *DecimalR = new QRadioButton(this);
DecimalR->setChecked(true); DecimalR->setDown(true);
QRadioButton *HexaR = new QRadioButton(this);
QHBoxLayout *hbox = new QHBoxLayout;
hbox->addWidget(OctalR);
hbox->addWidget(DecimalR);
hbox->addWidget(HexaR);
hbox->addStretch(1);
DisplayMode->setLayout(hbox);
mainLayout->addWidget(label);
Value = new QLCDNumber(this);
Value->setDigitCount(8);
Value->setSegmentStyle(QLCDNumber::Flat);
Value->display(mValue);
mainLayout->addWidget(Value);
/* mainLayout->addWidget(DisplayMode);*/
mainLayout->addWidget(OctalR);
mainLayout->addWidget(DecimalR);
mainLayout->addWidget(HexaR);
setLineWidth(3);
setLayout(mainLayout);
connect(OctalR, SIGNAL(clicked()), this, SLOT(setOctal()));
connect(DecimalR, SIGNAL(clicked()), this, SLOT(setDecimal()));
connect(HexaR, SIGNAL(clicked()), this, SLOT(setHexa()));
}
Call QLayout::setContentsMargins() for both mainLayout and hbox. Try (3, 3, 3, 3) as parameters for a starting point and tweak. Layouts have default margins of 11 pixels on most platforms, according to the docs.

How to add extra data to a member in MDS?

I'm running MDS on a virtual machine and trying to access the service from my host OS.
I've been able to add something to the database but my data is all over the place and in the Master Data Manager (website) I don't see the new member.
I suppose I shouldn't be using Attributes but something else but what and how? Are there tutorials because I can't find any ...?
Here's the code I'm using:
International international = new International();
EntityMembers entityMembers = new EntityMembers();
// Set the modelId, versionId, and entityId.
entityMembers.ModelId = new Identifier { Name = modelName };
entityMembers.VersionId = new Identifier { Name = versionName };
entityMembers.EntityId = new Identifier { Name = entityName };
entityMembers.MemberType = memberType;
Collection<Member> members = new Collection<Member>();
Member aNewMember = new Member();
aNewMember.MemberId = new MemberIdentifier() { Name = employee.FullName, Code = aNewCode, MemberType = memberType };
Collection<MDS.Attribute> attributes = new Collection<MDS.Attribute>();
MDS.Attribute attrOrgUnit = new MDS.Attribute();
attrOrgUnit.Identifier = new Identifier() { Name = "OrganizationalUnit" };
attrOrgUnit.Value = employee.OrganizationalUnit;
attrOrgUnit.Type = AttributeValueType.String;
attributes.Add(attrOrgUnit);
aNewMember.Attributes = attributes.ToArray();
members.Add(aNewMember);
entityMembers.Members = members.ToArray();
// Create a new entity member
OperationResult operationResult = new OperationResult();
clientProxy.EntityMembersCreate(international, entityMembers, false, out operationResult);
HandleOperationErrors(operationResult);
I have been able to fix my own problem.
First of all: creating separate variables with collections and converting them to arrays afterwards is not necessary. The code from the tutorials works but fails to mention that, when adding the service reference, you have to configure it (right-click on the service reference -> configure) to use Collections as "Collection type" instead of arrays and to generate message contracts.
Second, the code above with the attributes is correct and works perfectly. The problem I had which failed to add messages with attributes was unrelated. It was a connection/authentication problem between my Host OS and Guest OS.
Hope this helps someone.