Why doesn't my OpenSCAD model render correctly in thingiverse? - render

I created a parametric OpenSCAD model, and tried importing it into thingiverse customizer. However, it is supposed to look like this:http://i.stack.imgur.com/BXFsQ.jpg, but it looks closer to this: http://i.stack.imgur.com/rOF5b.png
Does thingiverse simply not render anything correctly, or is there a problem with the model (code reproduced below)
//Do Nothing = 0
//Increment = 1
//Decrement = 2
//Increment + Zerocheck = 3
//Decrement + Zerocheck = 4
//Text position:
//Top left: 0
//Left side inwards: 1
//Left side outwards: 2
/* [Instructions] */
//Instructions for the Left Counter
Left_counter = 0; // [0:Do Nothing,1:Increment,2:Decrement,3:Increment and Check Zero,4:Decrement and Check Zero]
//Instructions for the Middle Counter
Middle_counter = 0; // [0:Do Nothing,1:Increment,2:Decrement,3:Increment and Check Zero,4:Decrement and Check Zero]
//Instructions for the Right Counter
Right_counter = 0; // [0:Do Nothing,1:Increment,2:Decrement,3:Increment and Check Zero,4:Decrement and Check Zero]
//Hole that currently has no purpose
No_Purpose_Hole = 0; // [0:Don't create hole,1:Create hole]
/* [Text] */
//Text to show
Text="";
//Can be used for card number, description, etc.
Text_position=0;// [0:Top left corner (1-3 chars),1:Left side facing inwards (1-12 chars),2:Left side facing outwards (1-12 chars)]
/* [Hidden] */
$fn=30;
include <write/Write.scad>;
punchcard();
module punchcard(){
scale([25.4,25.4,25.4])
difference(){
card(Text);
union(){
if (Left_counter == 1)
hole(3);
if (Left_counter == 2)
hole(1);
if (Left_counter == 3){
hole(3);
hole(5);}
if (Left_counter == 4){
hole(1);
hole(5);}
if (Middle_counter == 1)
hole(2);
if (Middle_counter == 2)
hole(8);
if (Middle_counter == 3){
hole(2);
hole(4);}
if (Middle_counter == 4){
hole(8);
hole(4);}
if (Right_counter == 1)
hole(10);
if (Right_counter == 2)
hole(7);
if (Right_counter == 3){
hole(10);
hole(9);}
if (Right_counter == 4){
hole(7);
hole(9);}
if (No_Purpose_Hole == 1)
hole(6);
}}}
module card(text){
difference(){
cube([3.3,1.8,.1]);
translate([0,0,-.5])union(){
//positioning holes
translate([1.65,.25,0])
cylinder(d=.25,h=1);
translate([1.65, 1.55,0])
cylinder(d=.25,h=1);
//threading holes
for(x=[.125,3.175])
for(y=[.125,1.675])
translate([x,y,0])
cylinder(d=.125,h=1);
}
if (Text_position == 0)
translate([.4,1.675,.1])
scale([.04,.04,.1])
writecube(text = Text, face = "top", size = .01);
if (Text_position == 1)
translate([.1,.9,.1])
scale([.04,.04,.1])
rotate([0,0,90])
writecube(text = Text, face = "top", size = .01);
if (Text_position == 2)
translate([.1,.9,.1])
scale([.04,.04,.1])
rotate([0,0,-90])
writecube(text = Text, face = "top", size = .01);
}
}
module hole (position){
translate([.3*position,0.7,-.5])
union(){
cylinder(d=.2, h=1);
translate([-.1,0,0])
cube([.2,.3,1]);
translate([0,.3,0])
cylinder(d=.2, h=1);
}}

Can you please specify how the rendering of thing-verse is off? The second image simply looks like the rendering of OpenSCAD. If you have already found an answer to your question, please let me know about the answer.

Related

Kendo NumericTextBox with step and rounding

I want to setup kendoNumericTextBox to allow user input any integer number and set step to 1000. But when user enters any value and use spinner, it should update to next multiple of step.
For example:
enter 123, press spin up, value will be 1000
enter 1234, press spin up, value vill be 2000
Is it possible or only way is to handle spin event and modify value from there?
UPDATE:
Ok, guys, thnx for help.
I have this spin handler now and it seems to be working as expected.
function onSpin(e)
{
var currentvalue = kendo.parseInt(this.value());
if (currentvalue > 0)
{
this.value(Math.floor(currentvalue / this.step()) * this.step());
}
if (currentvalue < 0)
{
this.value(Math.ceil(currentvalue / this.step()) * this.step());
}
}
I have provided a dojo below with a potential solution for you:
https://dojo.telerik.com/UQohUjaP/2
I have created a function that will work on the spin and on change value so that it will step the value up/down on the value that you set e.g. 1000
the function is fairly simple and for brevity I have taken out the log statements here:
function onChange() {
var currentvalue = kendo.parseInt(this.value());
if (currentvalue > 0) {
currentvalue = Math.ceil(currentvalue / this.step()) * this.step();
} else if (currentvalue < 0) {
currentvalue = Math.floor(currentvalue / this.step()) * this.step();
} else {
currentvalue = 0;
}
this.value(currentvalue);
}
Unfortunately there doesn't seem to be a simple way of figuring out if the value has gone up or down so I am basically checking to see if the value is greater than 1 or less than 1 and then calculating the ceiling or the floor for the value and then stepping it in the right direction. in order to cater for zero we have a special condition which just sets the value to 0 assuming that is a valid value in your scenario
As you say, it's possible by listening to the spin event:
$("#numerictextbox").kendoNumericTextBox({
min: 0,
spin: function(e) {
var isUp = e.sender._key === 38,
isDown = e.sender._key === 40;
var m = Math.trunc(this.value()/1000),
value = isUp ? m + 1 : m;
this.value(value * 1000);
}
});
I doubt there's something out of the box, because your needs seem somewhat unusual.

Something strange with positioning text with custom font in Itext7

I'm working on a program that creates several pdf docs and puts different text in the same location in them.
Text should be placed in a particular area and if it doesn't fit it in width it should wrap. It also has a custom font and may be differently aligned in that area. It should be Vertically aligned to Top because when the area is laid out for three lines and I has only one, it should appear on the top. Finally, I need to preserve leading on the level of font-size.
It is important to be precise in text positioning (e.g. I need an upper left corner of "H" from "Hello world" to appear definitely at 0, 100).
Now, I'm using
canvas.showTextAligned(paragraph, 0, 300,
TextAlignment.valueOf(alignment),
VerticalAlignment.TOP);
However, when I try to implement it with different fonts it has a various offset from desired y = 300. Moreover, offset differ from font to font. For Helvetica (everywhere 50 fontSize is used) offset is about 13 px, for Oswald about 17 px and for SedgwickAveDisplay it is massive 90 px.
I added borders to paragraph for debugging purpose and things become more strange.
Helvetica:
SedgwickAveDisplay:
The full snippet of my code to create pdf is below:
public byte[] createBadgeInMemory(int i) throws IOException {
ByteArrayOutputStream out = new ByteArrayOutputStream();
PdfDocument newPdf = new PdfDocument(new PdfWriter(out));
srcPdf.copyPagesTo(1,1,newPdf);
PdfPage page = newPdf.getFirstPage();
PdfCanvas pdfCanvas = new PdfCanvas(page);
Canvas canvas = new Canvas(pdfCanvas, newPdf, pageSize);
File defaultFont = new File("src/main/resources/fonts/Helvetica.otf");
PdfFont font = PdfFontFactory
.createFont(fontPath == null ? defaultFont.getAbsolutePath() : fontPath,
PdfEncodings.IDENTITY_H, true);
String value = "Example word";
Paragraph paragraph = new Paragraph(value);
float textWidth = font.getWidth("Example", 50);
paragraph.setWidth(textWidth);
switch (alignment) {
case("CENTER"):
textWidth /= 2;
break;
case("RIGHT"):
break;
default:
textWidth = 0;
break;
}
paragraph.setFont(font)
.setFontSize(fontSize)
.setFixedLeading(fontSize)
.setFontColor(new DeviceRgb(red, green, blue))
.setMargin(0)
.setPadding(0);
paragraph.setBorderTop(new DashedBorder(Color.BLACK, 0.5f))
.setBorderBottom(new DashedBorder(Color.BLACK, 0.5f))
.setBorderRight(new DashedBorder(Color.BLACK, 0.5f));
paragraph.setHyphenation(new HyphenationConfig(0,
"Example".length()));
canvas.showTextAligned(paragraph,
0 + textWidth,
300,
TextAlignment.valueOf(alignment),
VerticalAlignment.TOP);
newPdf.close();
return out.toByteArray();
}
I also tried variant from here, but for some reason text inside rectangle cuts out at some point (for instance, if I have area width 100px and text snippet I put in that I know occupies exactly 100 px (with the help of font.getWidth(value)), I have my text cut at nearly 80 px).
I also haven't found a way to align text inside a rectangle.
This is the result with Rectangle. A solid border is Rectangle border. As you can see it cuts letter "t" in "Redundant". It also should contain "word" on the second line, but it doesn't.
I copied code from an example.
I need your help. What am I doing wrong or may be there is another way to layout text in particular area with alignment and font?
Thank you in advance.
Update 21.09.17
Also tried variant from this question with SedgwickAveDisplay:
paragraph.setHorizontalAlignment(HorizontalAlignment.LEFT);
paragraph.setVerticalAlignment(VerticalAlignment.TOP);
paragraph.setFixedPosition( 0, 300 - textHeight, "Example".length());
doc.add(paragraph);
The result is the same as on the second screenshot.
This is a font-specific problem. iText guesses information about font glyphs, namely the bboxes incorrectly.
There is a quick and dirty method to adjust this behavior. You can create a custom renderer for text and adjust the calculated positions in it. An example of such a class would be as follows:
class CustomTextRenderer extends TextRenderer {
private CustomTextRenderer(Text text) {
super(text);
}
#Override
public LayoutResult layout(LayoutContext layoutContext) {
LayoutResult result = super.layout(layoutContext);
Rectangle oldBbox = this.occupiedArea.getBBox().clone();
// you can also make the height more than font size or less if needed
this.occupiedArea.setBBox(oldBbox.moveUp(oldBbox.getHeight() - fontSize).setHeight(fontSize));
yLineOffset = fontSize * 0.8f; // here you config the proportion of the ascender
return result;
}
#Override
public IRenderer getNextRenderer() {
return new CustomTextRenderer((Text) modelElement);
}
}
In order that new rendering logic to be applied, you have to use it in the following way:
Text text = new Text(value);
text.setNextRenderer(new CustomTextRenderer(text));
Paragraph paragraph = new Paragraph(text);
Please note that you have to be very careful with this kind of low-level layouting, be aware of you are doing and use this as seldom as possible.
Finally, I created a variant that worked for me.
pdfCanvas.beginText()
.setFontAndSize(font, fontSize)
.setLeading(fontSize)
.moveText(0, 300);
numberOfLines = 0;
sumOfShifts = 0;
float maxWidth = computeStringWidth("Exaxple");
String[] words = value.split("\\s");
StringBuilder line = new StringBuilder();
line.append(words[0]);
float spaceWidth = computeStringWidth(" ") ;
float lineWidth;
for (int index = 1; index < words.length; index++) {
String word = words[index];
float wordWidth = computeStringWidth(word) ;
lineWidth = computeStringWidth(line.toString()) ;
if (lineWidth + spaceWidth + wordWidth <= maxWidth) {
line.append(" ").append(word);
} else {
showTextAligned(alignment, pdfCanvas, line.toString(), lineWidth, maxWidth);
line.delete(0, line.length());
line.append(word);
}
}
if(line.length() != 0) {
lineWidth = computeStringWidth(line.toString()) ;
showTextAligned(alignment, pdfCanvas, line.toString(), lineWidth, maxWidth);
}
pdfCanvas.endText();
As computeStringWidth(String str) I used
Toolkit.getToolkit().getFontLoader().computeStringWidth(String str, Font font);
from import com.sun.javafx.tk.Toolkit with Font from javafx.scene.text.Font. I've chosen it because I use it in other parts of my app.
showTextAligned(...) is my own method that looks this way:
private void showTextAligned(String alignment,
PdfCanvas pdfCanvas,
String line,
float lineWidth,
float maxWidth) {
switch (alignment) {
case "CENTER": {
float shift = (maxWidth - lineWidth) / 2 - sumOfShifts;
pdfCanvas.moveText(shift, 0);
if(numberOfLines == 0) pdfCanvas.showText(line);
else pdfCanvas.newlineShowText(line);
numberOfLines++;
sumOfShifts += shift;
break;
}
case "RIGHT": {
float shift = maxWidth - lineWidth - sumOfShifts;
pdfCanvas.moveText(shift, 0);
if(numberOfLines == 0) pdfCanvas.showText(line);
else pdfCanvas.newlineShowText(line);
numberOfLines++;
sumOfShifts += shift;
break;
}
default:
pdfCanvas.moveText(0, 0);
if(numberOfLines == 0) pdfCanvas.showText(line);
else pdfCanvas.newlineShowText(line);
numberOfLines++;
break;
}
}
In my project, I used my variant, because it gives me an opportunity to work with hyphenation deeper (for instance, I can in future add functionality to avoid putting prepositions as a last word in the line).

JavaFX: Cell renderer instance for a given row of a TableColumn

In JavaFX, how to get the cell renderer instance for a given cell of a given TableColumn?
In Swing, the way to do it would be to invoke getTableCellRendererComponent() on the TableCellRenderer for that column and pass it the row and column indices. But JavaFX seems to be very different. I tried searching and going through the TableColumn API but I don't seem to be able to figure this out. Maybe I have to do something with getCellFactory().
My goal is to query the preferred width for each cell renderer of a column and then calculate the width to set on the column so that the contents of all the cells of that column are fully visible.
A question was asked here - JavaFX 2 Automatic Column Width - where the goal of the original poster was the same as that of mine. But there hasn't been a satisfactory answer there yet.
There is resizeToFit() method in TableColumnHeader class. Unfortunately it is protected. How about just copy-paste the code to your application and change it a bit:
protected void resizeToFit(TableColumn col, int maxRows) {
List<?> items = tblView.getItems();
if (items == null || items.isEmpty()) return;
Callback cellFactory = col.getCellFactory();
if (cellFactory == null) return;
TableCell cell = (TableCell) cellFactory.call(col);
if (cell == null) return;
// set this property to tell the TableCell we want to know its actual
// preferred width, not the width of the associated TableColumn
cell.getProperties().put("deferToParentPrefWidth", Boolean.TRUE);//the change is here, only the first parameter, since the original constant is not accessible outside package
// determine cell padding
double padding = 10;
Node n = cell.getSkin() == null ? null : cell.getSkin().getNode();
if (n instanceof Region) {
Region r = (Region) n;
padding = r.getInsets().getLeft() + r.getInsets().getRight();
}
int rows = maxRows == -1 ? items.size() : Math.min(items.size(), maxRows);
double maxWidth = 0;
for (int row = 0; row < rows; row++) {
cell.updateTableColumn(col);
cell.updateTableView(tblView);
cell.updateIndex(row);
if ((cell.getText() != null && !cell.getText().isEmpty()) || cell.getGraphic() != null) {
getChildren().add(cell);
cell.impl_processCSS(false);
maxWidth = Math.max(maxWidth, cell.prefWidth(-1));
getChildren().remove(cell);
}
}
col.impl_setWidth(maxWidth + padding);
}
Then you can call the method after load data:
for (TableColumn clm : tblView.getColumns()) {
resizeToFit(clm, -1);
}

How to keep LongListSelector's current group name on top

I'm sure it has been asked before, but i cant find the answer. Is it possible using the LongListSelector control to always show the name of the current group? Just like it works in the People hub.
This is just a snippet. Please modify it as necessary.
var transform = llstItems.TransformToVisual(Application.Current.RootVisual);
Point pointTarget = transform.Transform(new Point(0, 0));
pointTarget.X += 5;
pointTarget.Y += 6;
List<UIElement> elements = (List<UIElement>)VisualTreeHelper.FindElementsInHostCoordinates(pointTarget, Application.Current.RootVisual);
if (elements != null && elements.Count > 0)
{
TextBlock textGroupedHeader = elements[0] as TextBlock;
if (textGroupedHeader != null)
{
Main.GroupTitle = textGroupedHeader.Text;
}
}
You can get the control as part of the Windows Phone Toolkit
https://nuget.org/packages/WPtoolkit

How can I change the state of the itemRenderer of one member of a flex 4 spark data group?

I have a "step indicator" made out of a DataGroup:
<s:DataGroup id="stepNumbers" itemRenderer="stepNumberRenderer" horizontalCenter="0">
<s:layout>
<s:HorizontalLayout verticalAlign="middle"/>
</s:layout>
</s:DataGroup>
where the dataprovider is 1,2,3,4,5.
The item renderer has 2 states, "normal" and "active". Within Actionscript, I’d like to be able to set each number to "active" in as needed. So, I need to set "2" to its active state, i.e. stepNumbers[1]. What's the syntax for this?
var item:stepNumberRenderer;
var active:int = 2;
for(var i:uint = 0; i < stepNumbers.numElements; i++)
{
item = stepNumbers.getElementAt(i) as stepNumberRenderer;
If(i == active)
item.currentState = "active";
else
item.currentState = "normal";
}

Resources