NX9/UG Knowledge Fusion script to add values to expressions - expression

I'm new to Knowledge Fusion, I'm trying to create a .dfa script that will add some values from a surface or solid to expressions, so I can then export to excel.
Here is what I have so far:
DefClass: centers (%nx_application %ui_comp);
(Boolean) %on_solid?: false;
(String Parameter) %ask_name: "Centers";
(string) %icon_name: "section_inertia";
(Integer) %edit_dialog: ug_invokeClassDialog(self:);
(List Uncached) %onObjectHighlight: centers:;
(Boolean) %atTimeStamp?: false;
(child) UI_Select: {
class, %ui_comp_selection;
Many, False;
Label, "Select surface or solid to analyse";
Tooltip, "Select the Surface or Solid to analyse";
FilterTriple, {{ 70, 0, 35 },{ 70, 0, 36 }};
};
(Instance) objet: ug_adoptObject(nth(1,UI_Select:SelectedObjects:));
This part finds the centers and add it to expressions:
(child uncached) x: {
Class, ug_expression;
Name, "x";
Value, localX(objet:centroid:);
};
(child uncached) y: {
Class, ug_expression;
Name, "y";
Value, localY(objet:centroid:);
};
(child uncached) z: {
Class, ug_expression;
Name, "z";
Value, localZ(objet:centroid:);
};
Now I'm trying to add surface area if the object selected is a surface, or volume is it is a solid body.
this is what I tried:
(child uncached) area: {
Class, ug_expression;
Name, "area";
Value, area(objet:surface_area:);
};
this didn't work, the application crashes, saying the is no class surface_area.
I also have no idea how to make an if statement in the language.
It has been super hard to create this, there is almost no info online and I couldn't find documentation on functions etc, everything so far as been trial and error.
would very much appreciate some help and guidance on this
Thank so much

I find out to find areas and volumes if anyone has the same problem.
Still could figure out how to do the if statement because I can't find a why to ask if object is a solid or surface.
However both work if both solids and surface, just give 0 for the volume of a surface obviously.
here is the code:
(child uncached) area: {
Class, ug_expression;
Name, "area";
Value, object:Surface_Area:;
};
(child uncached) Volume: {
Class, ug_expression;
Name, "Volume";
Value, object:Volume:;
};
How it help anyone trying to create custom NX functions

Related

Best Key to use when storing GameObjects in Hashtable? - Unity, C#

I'm working towards writing a script to take a "snapshot" of the initial attributes of all children of a GameObject. Namely at startup I want to save the position, orientation & color of all these objects in a Hashtable. The user has the ability to move & modify these objects during runtime, and I want to update the Hashtable to keep track of this. This will allow me to create an Undo last action button.
I found that gameObject.name isn't a good Key for my Hashtable entries because sometimes multiple game objects have the same name (like "cube"). So what would make a better Key? It's clear that Unity differentiate between two identical game objects with the same name, but how? I don't want to have to manually Tag every game object. I want to eventually bring in a large CAD file with hundreds of parts, and automatically record them all in a Hashtable.
For example, the code below works fine, unless I have multiple game objects with the same name. Then I get this error ArgumentException: Item has already been added. Key in dictionary: 'Cube' Key being added: 'Cube'
public class GetAllObjects : MonoBehaviour
{
public Hashtable allObjectsHT = new();
void Start()
{
Debug.Log("--Environment: GetAllObjects.cs <<<<<<<<<<");
foreach (Transform child in transform)
{
allObjectsHT.Add(child.gameObject.name, child);
}
}
}
Thanks Chuck this is what I want, and you solved my problem:
public class GetAllObjects : MonoBehaviour
{
UnityEngine.Vector3 startPosition;
UnityEngine.Quaternion startRotation;
public Hashtable allObjectsHT = new();
void Start()
{
Debug.Log("--Environment: GetAllObjects.cs <<<<<<<<<<");
foreach (Transform child in transform)
{
startPosition = child.position;
startRotation = child.rotation;
Hashtable objHT = new();
objHT.Add("position", startPosition);
objHT.Add("rotation", startRotation);
allObjectsHT.Add(child, objHT);
}
}
}
It's good to use meaningful keys you can refer to, otherwise you'd just use a collection without keys like a List. You could use an editor script to name all of the objects you import and use the names as keys. e.g.
int i = 0;
foreach(GameObject g in Selection.gameObjects)
{
g.name = "Object_" + i.ToString();
i++;
}
You could make the naming more sophisticated and meaningful of course, this is just an example.

check if d3.select or d3.selectAll

I have a method on a reusable chart that can be passed a selection and return a value if it is passed a d3.select('#id') selection or an array of values if it is passed a d3.selectAll('.class') selection. I'm currently interrogating the passed argument with context._groups[0] instanceof NodeList, but it feels a little fragile using an undocumented property, as that may change in future versions. Is there a more built in way of determining if a selection comes from select or selectAll?
selection.size() will not help here, as it only tells us the result of the selection, not how it was called.
EDIT:
Here's the context of the use. I'm using Mike Bostock's reusable chart pattern and this instance includes a method for getting/setting a label for a donut.
To me, this API usage follows the principle of least astonishment, as it's how I would expect the result to be returned.
var donut = APP.rotatingDonut();
// set label for one element
d3.select('#donut1.donut')
.call(donut.label, 'Donut 1')
d3.select('#donut2.donut')
.call(donut.label, 'Donut 2')
// set label for multiple elements
d3.selectAll('.donut.group-1')
.call(donut.label, 'Group 1 Donuts')
// get label for one donut
var donutOneLabel = d3.select('#donut1').call(donut.label)
// donutOnelabel === 'Donut 1'
// get label for multiple donuts
var donutLables = d3.selectAll('.donut').call(donut.label)
// donutLabels === ['Donut 1', 'Donut 2', 'Group 1 Donuts', 'Group 1 Donuts']
and the internal method definition:
App.rotatingDonut = function() {
var label = d3.local();
function donut() {}
donut.label = function(context, value) {
var returnArray;
var isList = context._groups[0] instanceof NodeList;
if (typeof value === 'undefined' ) {
// getter
returnArray = context.nodes()
.map(function (node) {return label.get(node);});
return isList ? returnArray : returnArray[0];
}
// settter
context.each(function() {label.set(this, value);});
// allows method chaining
return donut;
};
return donut
}
Well, sometimes a question here at S.O. simply doesn't have an answer (it has happened before).
That seems to be the case of this question of yours: "Is there a more built in way of determining if a selection comes from select or selectAll?". Probably no.
To prove that, let's see the source code for d3.select and d3.selectAll (important: those are not selection.select and selection.selectAll, which are very different from each other).
First, d3.select:
export default function(selector) {
return typeof selector === "string"
? new Selection([[document.querySelector(selector)]], [document.documentElement])
: new Selection([[selector]], root);
}
Now, d3.selectAll:
export default function(selector) {
return typeof selector === "string"
? new Selection([document.querySelectorAll(selector)], [document.documentElement])
: new Selection([selector == null ? [] : selector], root);
}
As you can see, we have only two differences here:
d3.selectAll accepts null. That will not help you.
d3.selectAll uses querySelectorAll, while d3.select uses querySelector.
That second difference is the only one that suits you, as you know by now, since querySelectorAll:
Returns a list of the elements within the document (using depth-first pre-order traversal of the document's nodes) that match the specified group of selectors. The object returned is a NodeList. (emphasis mine)
And querySelector only...:
Returns the first Element within the document that matches the specified selector, or group of selectors.
Therefore, the undocumented (and hacky, since you are using _groups, which is not a good idea) selection._groups[0] instanceof NodeList you are using right now seems to be the only way to tell a selection created by d3.select from a selection created by d3.selectAll.

How to set and/or retrieve default cell padding in iText 7

When you create a table in iText 7 using the Table and Cell classes, the table cells come with some padding built in by default. As far as I can tell by looking at a generated document, it appears to be about 2 PDF units.
Is there any way I can retrieve this value for use in calculations? Also, is there any way I can change this default, so that I can set my own padding to be used in all cells in all tables, instead of having to set it individually on every cell?
Please take a look at the iText 7: Building Blocks tutorial.
In the Before we start section, we see that every building block is derived from a class named ElementPropertyContainer. This class is a container of properties.
In the case of the Cell class, there is a set of properties that define the padding. You can get these properties the generic way (using a method of the AbstractElement class) like this:
System.out.println(cell.getProperty(Property.PADDING_LEFT));
System.out.println(cell.getProperty(Property.PADDING_RIGHT));
System.out.println(cell.getProperty(Property.PADDING_TOP));
System.out.println(cell.getProperty(Property.PADDING_BOTTOM));
But why make it difficult if you can also simply use convenience methods that is available in the BlockElement class:
System.out.println(cell.getPaddingLeft());
System.out.println(cell.getPaddingRight());
System.out.println(cell.getPaddingTop());
System.out.println(cell.getPaddingBottom());
As you can see in the tutorial, the Cell class is a subclass of the BlockElement class. The BlockElement is a subclass of the AbstractElement class. The AbstractElement class is a subclass of the ElementPropertyContainer class.
If you want to change the padding (or the margin if you are so inclined), please read chapter 5 of that tutorial. It has an example, named CellMarginPadding:
public void createPdf(String dest) throws IOException {
PdfDocument pdf = new PdfDocument(new PdfWriter(dest));
Document document = new Document(pdf);
Table table = new Table(new float[]{2, 1, 1});
table.setBackgroundColor(Color.ORANGE);
table.setWidthPercent(80);
table.setHorizontalAlignment(HorizontalAlignment.CENTER);
table.addCell(
new Cell(1, 3).add("Cell with colspan 3")
.setPadding(10).setMargin(5).setBackgroundColor(Color.GREEN));
table.addCell(new Cell(2, 1).add("Cell with rowspan 2")
.setMarginTop(5).setMarginBottom(5).setPaddingLeft(30)
.setFontColor(Color.WHITE).setBackgroundColor(Color.BLUE));
table.addCell(new Cell().add("row 1; cell 1")
.setFontColor(Color.WHITE).setBackgroundColor(Color.RED));
table.addCell(new Cell().add("row 1; cell 2"));
table.addCell(new Cell().add("row 2; cell 1").setMargin(10)
.setFontColor(Color.WHITE).setBackgroundColor(Color.RED));
table.addCell(new Cell().add("row 2; cell 2").setPadding(10)
.setFontColor(Color.WHITE).setBackgroundColor(Color.RED));
document.add(table);
document.close();
}
This is what it looks like:
I'm sorry if it hurts the eyes a bit, but using those colors seemed like the best way to explain the difference between the margin and the padding to me.
Most of the properties are inherited. For instance: if you set the font for a Div, that font will be the default font for all the elements added to that Div. There are some exceptions though. The padding is one of them. This is how the default values for the properties specific to the Cell class were defined:
#Override
public <T1> T1 getDefaultProperty(int property) {
switch (property) {
case Property.BORDER:
return (T1) (Object) DEFAULT_BORDER;
case Property.PADDING_BOTTOM:
case Property.PADDING_LEFT:
case Property.PADDING_RIGHT:
case Property.PADDING_TOP:
return (T1) (Object) 2f;
default:
return super.<T1>getDefaultProperty(property);
}
}
As you can see, there is no padding value for the complete cell; the padding consists of four values that incidentally are identical by default.
If you don't like to define a padding different from the default for each Cell, just create a subclass of Cell and call it MyCustomCell. Make it custom in the sense that it uses the padding of your choice by overriding the getDefaultProperty() class.
In the tutorial, you'll find an example of a subclass that draws cells with borders that have rounded corners so that we don't have to set declare a renderer every time we want to introduce rounder corners.
I am the original author of that documentation. I hope you find it useful to answer these and other questions about the Cell and other objects in iText 7.
I did this in C# per #Bruno Lowagie override route to set a default as no padding and no border:
public class BorderlessCell : Cell
{
public BorderlessCell(int rowSpan, int colSpan) : base(rowSpan, colSpan) { }
public BorderlessCell() : base() { }
public override T1 GetDefaultProperty<T1>(int property)
{
switch (property)
{
case Property.BORDER:
return (T1)(Object)(Border.NO_BORDER);
case Property.PADDING_BOTTOM:
case Property.PADDING_LEFT:
case Property.PADDING_RIGHT:
case Property.PADDING_TOP:
return (T1)(Object)(0);
default:
return base.GetDefaultProperty<T1>(property);
}
}
}
What works for me was editing the WidthPercentage, for example:
table.setWidthPercentage(100)

Calling Several Functions Linked With Classes at Certain Times with AS3

I'm working on a random wave system for a game. The idea is that every 1000 points a movement pattern would be selected from around 50 possibilities. This would affect the speed, direction, and image of the selected item. I have devised a method that I think will work, but I'm unsure if this is going to cost too much memory to run.
public class engine extends MovieClip {
private var countK:Number = 0;
private var newWave:Boolean = true;
public function engine() {
stage.addEventListener(Event.ENTER_FRAME, update);
}
private function update():void {
checkCount();
checkNew();
}
private function checkCount():void {
if (count => 1000) {
newWave=true;
count = 0;
}
}
private function checkNew():void {
if(newWave) {
randomNumber();
newWave=false
}
}
Above is my quick idea of getting a random number to be generated every 1000 points. Points can be added in any way you want (just add say 20 to "Score" and 20 to "count" at the same time). Where I can a random number function in checkNew, I won't be pulling another function, it's simply there for the sake of legibility.
var newEnemy:mEnemy =new mEnemy();
stage.addChild(newEnemy);
EnemyArray.push(newEnemy);
trace(EnemyArray.length);
Above is some code that can add an instance of mEnemy to the stage. Now where I'm starting to loose it is, how can I translate the random number into a viable method of changing mEnemy's behaviour?
Is it wise to have 50 functions inside the mEnemy class and just before I addChild, I do something like newEnemy.WAVEfuncton1(); ? If that is the case, can I save code by getting it to select the function without writing a whole bunch of if statements?
Instead of;
if (randomN==1) {
newEnemy.WAVEfunction1();
}
if (randomN==2) {
newEnemy.WAVEfunction2();
}
....
Can I do;
newEnemy.WAVEfunction[randomN]();
This is also assuming that using functions inside the enemy is the best idea. Is it better to have the behaviours inside the engine class instead?
As you can see, I'm no programmer. I'm very new to this sort of thinking and I don't want to create a mistake that will destroy the performance of the game (not to mention picking up bad habits too!).
If you have taken the time to read this question, thank you! If you tolerate my ignorance, then thank you even more!
If the wave functions are just creating a single enemy of a certain type, it might make more sense to make an array with the details of each type like this: (I'm guessing at how your enemies work of course)
private const ENEMY_TYPES:Array = [
{speed:1, direction:90, image:1},
{speed:2, direction:45, image:2}
]
then change mEnemy() to set itself up according to the details you give it:
public function mEnemy(details:Object) {
mySpeed = details.speed;
...
That way, you can just write new mEnemy(ENEMY_TYPES[randomN]);
Alternatively, if you do need to have lots of separate wave functions, you can use the [ ] array access operator to access the properties of an object such as newEnemy by name (or this to reference the current object):
var exampleProperty:String = "Hello.";
this["exampleProperty"];
So you can run your wave functions by writing:
newEnemy["WAVEfunction" + String(randomN)]();
A 2-year old question and rather non-actual already but let me try myself here as I have just signed up.
As I understood, what are you proposing to do here is writing all 50 behaviour methods for each kind of Enemy, which is of course not good.
First, you can add the "behaviour" entity. So each enemy now has a behaviour property.
Next, you have to create a separate Behaviour class or interface, which will have 50 subclasses (Behaviour1...Behaviour50), each subclass implementing its own run() method. Note that this way you will be able to add or remove behaviours without touching anything else. A basic implementation would look like this:
public class Behaviour() {
public function run(e:Enemy):void {
e.y += 10;
}
}
So you see, it's not like enemy is doing something. It's the Behaviour that does something with the enemy it was passed to.
Next, you need a mechanism to get the proper subclass from a given random number.
What you need is a Factory - a static class that will return different types of Behaviours based on input params. Something like this:
public class BehaviourFactory {
public static getBehaviour(n:int):Behaviour {
switch(n) {
case 1: return new Behaviour1();
case 2: return new Behaviour2();
// etc.
}
}
}
Instead of having 50 choices inside a switch, you can also use the class definition:
var c:Class = getDefinitionByName('Behaviour' + your_random_number) as Class;
return new c;
(In further implementatons it can be cached, stored in an Array etc.) After you have a Factory, you just do:
var b:Behaviour = BehaviourFactory.getBehaviour(your_random_number);
Next, you can use different approaches depending of how exactly the behaviour changes. For example, if the enemy is born with a specific current behaviour and it doesn't change during the enemy's lifetime, you can just assign one of Behaviour subclasses to the Enemy's behaviour property:
public class Enemy {
public var behaviour:Behaviour;
public function Enemy(b:Behaviour) {
this.behaviour = b;
}
}
var e:Enemy = new Enemy(BehaviourFactory.getBehaviour(random_number));
e.behaviour.run(e);
This property of course can also be changed dynamically so the next time it is run the enemy will behave differently.
If the behaviour is global for all enemies and changes for all of them at once, you don't event need to have a property in an Enemy object. You just have a global Behaviour object and pass there an Enemy instance:
var e:Enemy = enemy_list[i];
current_behaviour.run(e);
it will take care of processing each active enemy according to the currently chosen behaviour.
Finally, there's more interesting way to implement behaviours. Suppose you have several behaviour types that don't have anything in common. Say, the Enemy can be Crawling, Flying, Shooting and Poisonous. So let's say you're attempting to implement all possible combinations: Flying, FlyingShooting, FlyingPoisonous, FlyingShootingPoisonous, etc. You would have to create a Behaviour subclass for each of these combinations despite them having very common basic parts.
There's an other way to go, called the Decorator pattern. You simply write a method for each single quality. Whenever you need a combination of qualities, you simply create object with first quality and wrap it into the object with the second quality and wrap it into the object with the third quality etc. So your base Behaviour class needs one addition:
public class Behaviour {
private var parent_bhv: Behaviour;
public function Behaviour(bhv:Behaviour = null) {
if (bhv) this.parent_bhv = bhv;
}
public function run(e:Enemy):void {
e.y += 10; // do what we need to do
if (this.parent_bhv) this.parent_bhv.run(e); // pass to a next bhv.
}
}
Let's create compound behaviour of number 1, 3 and 15:
var decorated_behaviour:Behaviour = BehaviourFactory.getDecoratedBehaviour([1, 3, 15]);
let's also add the corresponding BehaviourFactory method:
public class BehaviourFactory {
public static function getDecoratedBehaviour(bhv_list:Array):Behaviour {
var b:Behaviour = null;
for (var i:int = 0; i < bhv_list.length; i++) {
var c:Class = getDefinitionByName('Behaviour' + bhv_list[i]) as Class;
b = new c(b);
}
return b;
}
}
Now you're all set without having to code all possible combinations!

What is the MVC equivalent of this code:

Here's the easy pseudo-code:
void TextBox1Changed()
{
//If the text isn't a number, color it red
if (!IsValidNumber(TextBox1.Text)
TextBox1.Color = Pink;
else
TextBox1.Color = WindowColor;
}
What's the MVC enterprisey version?
Not trying to be language specific, but the idea is to create a number text control that knows if the value is valid. It's easy to get hung up on the exact roles of M, V, and C. However, for all practical purposes, it makes sense to combine the View and the Controller for Desktop like applications. Swing took that approach because the controller and view had very tight coupling and it made sense to combine them into one. Read up this nice discussion on c2 about the topic.
class NumberTextBox extends TextBox {
bool isValid() {
return IsValidNumber(this.Value);
}
}
ageTextBox = new NumberTextBox();
ageTextBox.addChangeHandler(function() {
this.Color = this.isValid ? WindowColor : Pink;
});

Resources