Comparar commits

...

2967 Commits

Autor SHA1 Mensagem Data
Tim Kuipers 1730923083 safety: skip mesh if layer nr too high (CURA-1134) 2016-11-30 17:54:37 +01:00
Tim Kuipers 8e5a936522 fix: wrong indexing in part.insets for GCodePlanner::moveInsideCombBoundary (CURA-1134) 2016-11-30 17:44:03 +01:00
Tim Kuipers d29da8f7f8 refactor: change is_inside and was_inside from bool to SliceLayerPart* so that we know inside what part we were/are inside (CURA-1134)
makes for a better moveInsideCombBoundary functionality
2016-11-30 17:43:25 +01:00
Tim Kuipers ad56ce8866 fix: don't comb on raft layers or filler layers (CURA-1134) 2016-11-30 17:40:04 +01:00
Tim Kuipers 565b09e37d feat: SliceDataStorage::getPartInside (CURA-1134) 2016-11-30 17:38:40 +01:00
Tim Kuipers edc9767912 fix: made Polygons::inside virtual and let PolygonsPart::inside override it (CURA-1134) 2016-11-30 17:38:12 +01:00
Tim Kuipers ce6f58f136 info: comment on combing move inside dist (CURA-1134) 2016-11-30 16:50:58 +01:00
Tim Kuipers 5b941d07ff refactor: max_moveInside_distance2 ==> max_move_inside_distance2 (CURA-1134) 2016-11-30 16:48:01 +01:00
Tim Kuipers 350b42052a fix: better move inside so that we don't move inside the wrong part (CURA-1134)
the move inside is performed so that we don't perform the retraction on the outer wall, which causes a clearly visible z seam
2016-11-28 17:57:01 +01:00
Tim Kuipers 0ba152d081 fix: only conclude the startPoint is not inside after all when it doesn't collide with the outline and we are combing also over skin (CURA-1134) 2016-11-28 17:14:48 +01:00
Tim Kuipers 2c70c2ecb7 refactor/fix: compute was_inside for new layer rather than using the last is_inside of the previous layer heuristically (CURA-1134) 2016-11-28 15:44:09 +01:00
Tim Kuipers 4da8c6d8e7 fix: no more aabb hit check fails (CURA-2992) 2016-11-28 14:35:13 +01:00
Tim Kuipers c5ce425924 fix: no more use of deleted memory by optional (CURA-3008) 2016-11-28 14:34:45 +01:00
Tim Kuipers c74d4f7550 Revert "feat: PolygonPointer as distinct from PolygonRef (CURA-3008)"
This reverts commit 20cd4275fc.
2016-11-28 13:43:03 +01:00
Tim Kuipers 19f093e0cc safety: assert on optional::instance (CURA-3008) 2016-11-28 13:42:36 +01:00
Tim Kuipers 2a4cca0402 fix: use ClosestPolygonPoint::isValid where neccesary (CURA-3008) 2016-11-28 13:40:54 +01:00
Tim Kuipers 32804c102c fix: use optional<PolygonRef> instead of PolygonPointer (CURA-3008) 2016-11-28 13:40:02 +01:00
Tim Kuipers 776f56fc37 lil fix: no more un/signed int comaprison 2016-11-28 12:18:13 +01:00
Tim Kuipers a92cd23e62 safety: extra assert for too many nozzle switches in a layer 2016-11-25 16:10:10 +01:00
Tim Kuipers 4725001564 fix: remove printing_temperature_command if precooling goes further back (CURA-1932)
If the precooling command will precede the printing temeprature command to heat to the temp of the next layer, then don't use that temp;
we should already be cooling down, rather than heating toward the temp of the next layer.
2016-11-25 14:00:26 +01:00
Tim Kuipers a18595877f safety: extra assert on temp in NozzleTempInsert (CURA-1932) 2016-11-25 14:00:26 +01:00
Tim Kuipers 40e7c450d5 fix: getCoolDownPointAfterWarmUp outer_temp was switched (CURA-1932)
This caused the timing of the precool command to be off
2016-11-25 14:00:26 +01:00
Tim Kuipers 13a0b11d68 fix: don't use material_print_temperature_layer_0 if it's zero (CURA-1932) 2016-11-25 14:00:26 +01:00
Ghostkeeper 4fc69f608a Fix max extruder height if only using bed adhesion
If an extruder only prints bed adhesion, the maximum extruder height for that extruder is now correct.

Contributes to issue CURA-2993.
2016-11-25 11:21:59 +01:00
Ghostkeeper deb577d559 Make extruder numbers const and unsigned
This is in line with the first one, and more correct.

Contributes to issue CURA-2993.
2016-11-25 11:17:45 +01:00
Ghostkeeper c8161da3eb Remove spaces within brackets
As per our code style.

Contributes to issue CURA-2993.
2016-11-25 11:16:30 +01:00
Ghostkeeper 87733834d1 Expand documentation for computePrintHeightStatistics
Should make it more overseeable.

Contributes to issue CURA-2993.
2016-11-25 11:08:29 +01:00
Ghostkeeper b9aeea425f Correct documentation of computePrintHeightStatistics
It's initialised, not uninitialised (or unitialised).

Contributes to issue CURA-2993.
2016-11-25 11:01:51 +01:00
Tim Kuipers 44b3039db6 optimization: use already computed ClosestPolygonPoint for ensureInsideOrOutside during combing crossing calculation (CURA-2229) 2016-11-24 15:09:41 +01:00
Tim Kuipers 6476270cf6 fix: combing start crossing inside location was sometimes on the destination part, rather than the starting part (CURA-2229) 2016-11-24 13:56:57 +01:00
Ghostkeeper e532f3ddda Merge branch 'feature_anti_support' 2016-11-22 16:36:52 +01:00
Tim Kuipers 7aaab151e7 fix: better handling of edge cases for Preheat::getCoolDownPointAfterWarmUp and getWarmUpPointAfterCoolDown (CURA-3006) 2016-11-22 14:54:59 +01:00
Tim Kuipers 0353433919 fix: also ensure prime after first layer of raft (CURA-3006) 2016-11-22 14:52:21 +01:00
Tim Kuipers 40a6c495c7 refactor: move code from FffGcodeWriter::processLayer into new FffGcodeWriter::ensureAllExtrudersArePrimed (CURA-3006) 2016-11-22 14:51:48 +01:00
Ghostkeeper cfa6758911 Merge branch 'fix_support_order'
Conflicts:
	src/FffGcodeWriter.cpp
	src/PrimeTower.cpp
2016-11-22 13:03:38 +01:00
Tim Kuipers f6b29b1d8a Merge branch 'feature_anti_support' of github.com:Ultimaker/CuraEngine into feature_anti_support 2016-11-22 10:21:44 +01:00
Ghostkeeper bd79a8468e Merge branch 'feature_hollow_prime_tower' 2016-11-22 09:19:16 +01:00
Ghostkeeper 35dcc6906f Merge branch 'feature_precool' 2016-11-21 17:35:40 +01:00
Tim Kuipers db7bc279ee fix: removeEmptyFirstLayers can still remove even when support was generated (but removed by anti support meshes (CURA-2077) 2016-11-21 16:50:26 +01:00
Tim Kuipers a7ea623266 fix: removeEmptyFirstLayers can still remove even when support was generated (but removed by anti support meshes (CURA-2077) 2016-11-21 16:34:55 +01:00
Tim Kuipers 724589c13a fix: support towers went all the way to the bed (CURA-2077) 2016-11-21 16:31:52 +01:00
Tim Kuipers db1fa098ad Merge branch 'master' into feature_anti_support 2016-11-21 16:12:57 +01:00
Tim Kuipers be99db30c0 fix: combing referenced element zero of a polygons (CURA-3008) 2016-11-21 15:54:07 +01:00
Tim Kuipers 9456592dd7 fix: use PolygonPointer in ClosestPolygonPoint (CURA-3008)
sometimes functions cannot return a ClosestPolygonPoint, or we start with an empty one untill we find any point

cherry-picked from 4634338c7d
2016-11-21 15:45:27 +01:00
Tim Kuipers 20cd4275fc feat: PolygonPointer as distinct from PolygonRef (CURA-3008)
It was a bad idea to change PolygonRef into PolygonPointer, because then we'd have to check whether it is a nullptr all over the engine...

cherry-picked from a2a8604c72
2016-11-21 15:38:12 +01:00
Tim Kuipers 67697d5258 fix: handle modulo operations for negative layer numbers (CURA-2789) 2016-11-21 14:18:39 +01:00
Tim Kuipers 7d8e4de7ba fix: prime tower didn't get added in filler layers (CURA-2789)
PrimeTower always received layer_nr=0 for those layers, so i had to propagate the negative layer numbers to addSupportToGcode and to PrimeTower
2016-11-21 14:17:32 +01:00
Tim Kuipers 2486120a38 fix: don't send polygons over command socket during planning phase (CURA-2789)
The polygons of the prime tower were also sent on the wrong layer / height, causing it to be visualized within raft layers
2016-11-21 14:13:56 +01:00
Tim Kuipers 43c8f2a913 fix: print prime tower directly after platform adhesion on layer 0 (CURA-2789) 2016-11-21 13:19:25 +01:00
Ghostkeeper dd8b57b666 Merge branch 'master' of github.com:Ultimaker/CuraEngine 2016-11-18 15:51:10 +01:00
Jaime van Kessel 72ed492a61 Merge branch 'feature_alternate_carving' of github.com:Ultimaker/CuraEngine 2016-11-18 15:14:12 +01:00
Ghostkeeper c02482590f Merge branch 'feature_fill_small_gaps' 2016-11-18 15:05:58 +01:00
Tim Kuipers f32e2d9554 Merge branch 'master' into feature_anti_support 2016-11-18 14:07:29 +01:00
Jaime van Kessel bf61814849 Merge branch 'feature_fan_speed_0' of github.com:Ultimaker/CuraEngine 2016-11-18 10:43:56 +01:00
Jaime van Kessel 5741e79ade Merge branch 'master' of github.com:Ultimaker/CuraEngine 2016-11-18 10:42:17 +01:00
Jaime van Kessel 09419fd6be Merge branch 'feature_bed_adhesion_none' of github.com:Ultimaker/CuraEngine 2016-11-18 10:35:29 +01:00
Tim Kuipers a002f4b3b2 feat: alternate_carve_order (CURA-2992) 2016-11-17 19:58:31 +01:00
Tim Kuipers 25c7ccb0d3 fix: outside combing put starting and ending points of basic comb path on the wrong side (CURA-2988)
basic comb paths started on the wrong side, then followed the polygon on the right side and ended on the wrong side again
2016-11-17 17:22:53 +01:00
Tim Kuipers 58a99a403b fix: createLocToLineGrid didn't create any cells and copied the hashmap (CURA-2988)
std::bind doesn't allow for binding by reference
2016-11-17 17:01:57 +01:00
Tim Kuipers dd8594b200 fix: inside combing put starting and ending points of basic comb path on the wrong side (CURA-2988)
basic comb paths started on the wrong side, then followed the polygon on the right side and ended on the wrong side again
2016-11-17 17:00:23 +01:00
Ghostkeeper 6df5368cb9 Update variable names in documentation
The variable names were changed but changed incorrectly here.

Contributes to issue CURA-1932.
2016-11-17 14:49:29 +01:00
Ghostkeeper 3a038a2cd2 Put correct bounding box in g-code header
This is according to the Griffin header specification.

Contributes to issue CURA-2625.
2016-11-17 13:35:59 +01:00
Tim Kuipers 9613e186a3 docs: fixed docs location and included precool diagram in LayerPlanBuffer (CURA-1932) 2016-11-16 17:54:11 +01:00
Tim Kuipers 82b2362b2d lil compiler warning removal (CURA-1932) 2016-11-16 16:52:54 +01:00
Tim Kuipers a6ee34602c refactor: rename rediculous timeBeforeEndToInsertPreheatCommand_coolDownWarmUp ==> sensible getWarmUpPointAfterCoolDown and vice versa (CURA-1932) 2016-11-16 16:50:05 +01:00
Tim Kuipers 05d29eabcd refactor: timeBeforeEndToInsertPreheatCommand arguments better names (CURA-1932) 2016-11-16 16:41:18 +01:00
Tim Kuipers f7e3534a79 fix: update outdated function signature (add const and better naming) (CURA-1932) 2016-11-16 16:30:56 +01:00
Tim Kuipers bd4972e466 refactor: rename function argument to better match the intent (CURA-1932) 2016-11-16 16:27:44 +01:00
Tim Kuipers 0acf3beec2 fix: insertFinalPrintTempCommand: compute weighted average_print_temp by taking time into account (CURA-1932)
note that the print temp statistic doesn't really matter that much
2016-11-16 16:20:51 +01:00
Tim Kuipers 081055be46 fix: better documentation for LayerPlanBuffer::insertFinalPrintTempCommand (CURA-1932) 2016-11-16 16:17:42 +01:00
Ghostkeeper 560d23d3f2 Simplify skipping current extruder in calculateExtruderOrder
These are equivalent, but the code is now simpler.

Contributes to issue CURA-2789.
2016-11-16 12:51:50 +01:00
Tim Kuipers 44e7b0e0be fix: apply outer wall line width offset for interperimeter gaps (CURA-2306) 2016-11-16 10:18:40 +01:00
Tim Kuipers 8c48d1ce82 fix: material_extrusion_cool_down_speed handled correctly (CURA-1932)
it was handled as if the inverse (in s/*c) was the modifier rather than the original (in *C/s)
2016-11-15 17:53:38 +01:00
Tim Kuipers 8432e9ed9f fix: first start of extruder, require print temp rather than initial print temp (CURA-1932) 2016-11-15 17:52:07 +01:00
Tim Kuipers 1b014199c9 refactor: store initial_printing_temperature in ExtruderPlan (CURA-1932) 2016-11-15 17:46:47 +01:00
Tim Kuipers 7e0c5c6323 refactor: replaced timeBeforeEndToInsertPreheatCommand_warmUp by getTimeToGoFromTempToTemp (CURA-1932)
both functions actually tried to do the same thing
2016-11-15 17:42:37 +01:00
Tim Kuipers 9ada0901a6 refactor: insertPreheatCommands ==> insertTempCommands (CURA-1932) 2016-11-15 17:38:26 +01:00
Tim Kuipers d60d32a5d8 fix: exposed less internal functions of LayerPlanBuffer (CURA-1932) 2016-11-15 14:38:15 +01:00
Tim Kuipers 667c00aa5a lil assert (CURA-1932) 2016-11-15 14:37:32 +01:00
Tim Kuipers cf0ca05843 fix: insert initial/final print temp commands for groups of extruder plans rather than each (CURA-1932)
before this we would get precool and preheat during a layer change even when the last extruder of the previous layer is the first extruder of the next...
2016-11-15 14:37:07 +01:00
Tim Kuipers 3bcabacef4 fix: wrong check whether initial print temp was unused (CURA-1932) 2016-11-14 17:50:08 +01:00
Tim Kuipers b5801ea847 fix: warmUpCoolDown computed cool_down_time as if it was warm_up_time (CURA-1932) 2016-11-14 17:50:08 +01:00
Tim Kuipers 1bb90a2f03 fix: use more accurate coolDownWarmUp time estimations (CURA-1932)
with the initial and final printing temperature the old assumption didn't hold any more:
'Assumes from_temp is approximately the same as @p temp'

It uses the same logic as timeBeforeEndToInsertPreheatCommand_warmUpCoolDown(.)
2016-11-14 17:50:08 +01:00
Tim Kuipers cf55aef52b fix: for warmUpCoolDown compute max temp accurately (CURA-1932)
Didn't take extra heating time into account
2016-11-14 17:50:08 +01:00
Tim Kuipers c0f7538fdb fix: take care of during_printing for heatup/cooldown timings (CURA-1932) 2016-11-14 17:50:08 +01:00
Tim Kuipers 395ab9b7cd fix: warmup and cooldown times were incorrect (CURA-1932) 2016-11-14 17:50:08 +01:00
Tim Kuipers 80ecabb618 refactor: move Preheat functions to cpp file (CURA-1932) 2016-11-14 17:50:08 +01:00
Tim Kuipers ff291cc4d1 fix: insert temp commands for preheat and precool (CURA-1932)
insert heat command from initial_print_temp to print_temp at the first extrusion in a layer plan
insert cool command from print_temp to final_print_temp during the last extrusion moves in a layer plan
2016-11-14 17:50:08 +01:00
Tim Kuipers 4183835d2b fix: use initial_print_temp where print_temp used to be used (CURA-1932)
heating up is now done toward initial_print_temp
and the required temp at the start of a layer is initial_print_temp
2016-11-14 17:50:08 +01:00
Tim Kuipers 0e24d8db47 cleanup: no more boolean trappiness (CURA-1932) 2016-11-14 17:50:08 +01:00
Tim Kuipers f7bde54869 feat: some handy Preheat functions (CURA-1932) 2016-11-14 17:50:08 +01:00
Tim Kuipers bf8f027a97 setting: material_initial_print_temperature, material_final_print_temperature (CURA-1932) 2016-11-14 17:50:08 +01:00
Tim Kuipers 60625ea4bf refactor: ExtruderPlan::required_temp ==> printing_temperature (CURA-1932) 2016-11-14 17:50:08 +01:00
Tim Kuipers a9f6ae1943 refactor: rewrote logic in FffGcodeWriter::calculateExtruderOrder (CURA-2789) 2016-11-14 17:49:16 +01:00
Tim Kuipers cd01d7051b refactor: support_skin ==> support_interface (CURA-2789) 2016-11-14 17:49:16 +01:00
Ghostkeeper bd126bb841 Fix typo in assert message
Contributes to issue CURA-2789.
2016-11-14 17:49:16 +01:00
Tim Kuipers f1b3fb3cd6 refactor/fix: plan extruders independently of meshes and plan support per extruder plan (CURA-2789)
When printing dual color models with dual support (different support infill extruder than support skin extruder)
all support would either be printed before all models or after, leading to two extruder switches in one layer.

Now the extruder_order is calculated independently of the mesh_order and the support is added per extruder plan.

The support is always added first, so that:
- in single extrusion we never print in order support-support-model-model which would lead to model being printed on top of model which hasn't cooled enough
- in dual color, dual support we always print E1-support-model-support-model-E2-support-model-support-model so that oozle is automatically wiped on support
2016-11-14 17:49:16 +01:00
Tim Kuipers d48f06db0e refactor/fix: return whether support was added to extruder plan and only switch extruder if plans were added (CURA-2789) 2016-11-14 17:49:16 +01:00
Tim Kuipers 5567b06ed4 cleanup: remove unused parameter to FffGcodeWriter::addSupportToGCode (CURA-2789) 2016-11-14 17:49:16 +01:00
Tim Kuipers e87b11179f fix: getExtrudersUsed only include platform adhesion for first layer(s) (CURA-2789) 2016-11-14 17:49:16 +01:00
Tim Kuipers a17fef9d4b refactor: separate handleSupportBeforeModels out of FffGcodeWriter::addSupportToGCode (CURA-2789) 2016-11-14 17:49:16 +01:00
Tim Kuipers 4c49bf7894 cleanup: const-correctness for SliceDataStorage::getExtrudersUsed (CURA-2789) 2016-11-14 17:49:16 +01:00
Tim Kuipers bcb0ded784 fix: print support consecutive instead of always at end of layer (CURA-2789)
also support_interface_extruder_nr mattered even if the interface was turned off
2016-11-14 17:49:16 +01:00
jack 54ba25e7f5 Merge pull request #411 from Ultimaker/bugfix_prime_tower_too_high
CURA-2633 fix: limit prime tower height when support is touching buildplate onl…
2016-11-14 14:57:13 +01:00
Tim Kuipers 84a7f401a2 lil indent fix only (CURA-759) 2016-11-14 12:41:58 +01:00
Tim Kuipers 6afdf19ce4 feat: adhesion_type none (CURA-759) 2016-11-14 12:41:29 +01:00
Tim Kuipers 4aa1cc47f4 fix: don't start output decimal numbers with the decimal dot 2016-11-11 17:23:53 +01:00
Tim Kuipers 166473596a fix: compute perimeter_gaps for zigzag skin infill (CURA-2306) 2016-11-11 16:00:35 +01:00
Tim Kuipers feb21b67d1 fix: turn off gap filling if fill_perimeter_gaps is set to nowhere (CURA-2306) 2016-11-11 14:58:59 +01:00
Tim Kuipers dae7ec184f removal: remove skin option from fill_perimeter_gaps mode (CURA-2306) 2016-11-11 14:44:48 +01:00
Tim Kuipers cd170cae99 Revert "cleanup: removed fill_perimeter_gaps setting (CURA-996)"
This reverts commit 9c47644e55.

This reintroduces the fill_perimeter_gaps setting (CURA-2306)
2016-11-11 14:41:33 +01:00
Tim Kuipers d47d0a2e46 fix: handle perimeter_gaps for concentric skin infill (CURA-2306) 2016-11-11 14:37:51 +01:00
Tim Kuipers f0d59db203 refactor: optionally pass down perimeter_gaps to Infill constructor (CURA-2306) 2016-11-11 14:37:14 +01:00
Tim Kuipers f34a4e566b feat: handle perimeter_gaps between skin walls (CURA-2306) 2016-11-11 14:35:43 +01:00
Tim Kuipers 9c1ef177d1 feat: perimeter gaps for normal walls (CURA-2306) 2016-11-11 14:33:45 +01:00
Tim Kuipers e1c7e86b66 fix: optimize skin part order (CURA-2306) 2016-11-11 14:29:32 +01:00
Tim Kuipers 79d1074d47 feat: cool_fan_speed_0 (CURA-2182) 2016-11-10 16:41:42 +01:00
Tim Kuipers 348ca93dcb fix: add more special casing to ignore (anti)support meshes (CURA-2077) 2016-11-09 17:27:59 +01:00
Tim Kuipers e70b3c099f Merge branch 'fix_support_order' of github.com:Ultimaker/CuraEngine into fix_support_order 2016-11-09 16:40:50 +01:00
Tim Kuipers 8c9858a14c refactor: rewrote logic in FffGcodeWriter::calculateExtruderOrder (CURA-2789) 2016-11-09 16:38:14 +01:00
Tim Kuipers 6e56cb3416 refactor: support_skin ==> support_interface (CURA-2789) 2016-11-09 16:31:43 +01:00
Ghostkeeper 8761ae1e53 Merge branch 'feature_retract_at_layer_change' 2016-11-09 13:37:48 +01:00
Ghostkeeper d32be27b50 Fix typo in assert message
Contributes to issue CURA-2789.
2016-11-09 11:58:48 +01:00
Tim Kuipers 11b33215a2 fix: set extruder count (CURA-2325) 2016-11-09 10:24:31 +01:00
Tim Kuipers e8a31f1380 fix: remove GCodePlanner::makeLastPathZhopped (CURA-2325) 2016-11-09 10:24:31 +01:00
Ghostkeeper 7cbfb22f1f )
'I have to sort my books' she cried,
With self-indulgent glee;
With senseless, narcissistic pride:
'I'm just so OCD.'

'How random guys,' I smiled and said,
Then left without a peep -
And washed my hands until they bled,
And cried myself to sleep.
2016-11-09 10:24:24 +01:00
Tim Kuipers 40e6aac22b fix: only wipe in the middle of the prime tower if it's hollow (CURA-2325) 2016-11-09 10:24:24 +01:00
Tim Kuipers 33cc601a1b fix: only wipe on inside of prime tower if z hops are already being performed (CURA-2325) 2016-11-09 10:24:24 +01:00
Tim Kuipers d50b0c9c2f fix: go down on middle of hollow wipe tower (CURA-2325) 2016-11-09 10:24:24 +01:00
Tim Kuipers 77f415be61 fix: made hollow prime tower robust against zero wall thickness (CURA-2325) 2016-11-09 10:24:24 +01:00
Tim Kuipers 1aa784e521 doc update prime tower (CURA-2325) 2016-11-09 10:24:24 +01:00
Tim Kuipers ef8258da2f fix: make move to prime location z-hopped (CURA-2325) 2016-11-09 10:24:24 +01:00
Tim Kuipers 79692200b0 fix: make move toward hollow prime tower always z hopped (CURA-2325) 2016-11-09 10:24:24 +01:00
Tim Kuipers 966912ccc5 fix: more prime positions cause inside of hollow prime tower is quite big (CURA-2325) 2016-11-09 10:19:15 +01:00
Tim Kuipers 1513dcad5c fix: add brim on inside of hollow prime tower (CURA-2325)
even when we have selected to generate brim only for outside polygons
2016-11-09 10:19:15 +01:00
Tim Kuipers 41050ac835 fix: wipe on middle of prime tower (CURA-2325) 2016-11-09 10:19:15 +01:00
Tim Kuipers fb8625756f fix: return *this for operator= (CURA-2325) 2016-11-09 10:19:15 +01:00
Tim Kuipers 886bab29f7 refactor: cache prime tower walls as well as infill (CURA-2325) 2016-11-09 10:19:15 +01:00
Tim Kuipers 5bdf538d35 lil cleanup prime tower (CURA-2325) 2016-11-09 10:19:14 +01:00
Tim Kuipers 7d5040e283 feat: hollow prime tower (CURA-2325) 2016-11-09 10:19:14 +01:00
Tim Kuipers a49ed9a90e cleanup: removed unused var in PrimeTower (CURA-2325) 2016-11-09 10:19:14 +01:00
Tim Kuipers 7a4e732f3b refactor: pass along new_extruder to wipe tower generator functions (CURA-2325) 2016-11-09 10:19:14 +01:00
Tim Kuipers 653ce82255 fix: make wipe settings settable per extruder (CURA-2325) 2016-11-09 10:19:14 +01:00
Tim Kuipers 0b1df81945 feat: separate setting for pre-wipe (CURA-2325) 2016-11-09 10:19:14 +01:00
Tim Kuipers f65993c5b6 fix: put prime_tower_wipe_enabled back to old functionality (CURA-2325) 2016-11-09 10:19:14 +01:00
Ghostkeeper df91b3d8aa Merge branch 'feature_extruder_temp_layer_0' 2016-11-08 14:46:45 +01:00
Tim Kuipers 4b58ab0ad9 refactor/fix: plan extruders independently of meshes and plan support per extruder plan (CURA-2789)
When printing dual color models with dual support (different support infill extruder than support skin extruder)
all support would either be printed before all models or after, leading to two extruder switches in one layer.

Now the extruder_order is calculated independently of the mesh_order and the support is added per extruder plan.

The support is always added first, so that:
- in single extrusion we never print in order support-support-model-model which would lead to model being printed on top of model which hasn't cooled enough
- in dual color, dual support we always print E1-support-model-support-model-E2-support-model-support-model so that oozle is automatically wiped on support
2016-11-08 11:36:28 +01:00
Tim Kuipers 9cbdfd2152 refactor/fix: return whether support was added to extruder plan and only switch extruder if plans were added (CURA-2789) 2016-11-08 11:30:16 +01:00
Tim Kuipers 4a0a0088fe cleanup: remove unused parameter to FffGcodeWriter::addSupportToGCode (CURA-2789) 2016-11-07 17:49:35 +01:00
Ghostkeeper dc37384ffd Merge branch 'bugfix_support_retractions' 2016-11-07 15:40:08 +01:00
Tim Kuipers 2a21e6c348 fix: don't write temperature gcode commands for the UM2 family (CURA-2781, CURA-2736)
they are fixed by the firmware
2016-11-07 15:16:43 +01:00
Tim Kuipers 30011a5285 fix: insert preheat commands even in single extruder mode (CURA-2736) 2016-11-07 13:56:22 +01:00
Tim Kuipers 965b28e009 fix: compiler warnings for unsigned layer_nr and extruder_nr (CURA-2736) 2016-11-07 13:55:22 +01:00
Tim Kuipers 1b37007003 feat: initial layer extruder temp (CURA-2736) 2016-11-07 13:48:48 +01:00
Tim Kuipers 5cf0bcd399 feat: add is_initial_layer to layerplan and extruderplan (CURA-2736) 2016-11-07 13:48:48 +01:00
Tim Kuipers 0930d61dad feat: material_bed_temperature_layer_0 (CURA-2781)
set bed temeprature to normal at first layer
set bed temp to initial layer bed temp the first layer of each next meshgroup (one-at-a-time mode)
wait for initial bed temp to be reached
don't wait for second layer bed temp
2016-11-07 13:48:48 +01:00
Tim Kuipers a181977ce9 refactor: moved command line settings to fdmprinter.def.json (CURA-566)
also fixed some problems:
- type of one setting was string rather than str
- there were some old unused settings in there (prime_tower_outward_dir, machine_prinbt_temp_wait)
2016-11-07 11:59:13 +01:00
Ghostkeeper 3ab19f2f29 Merge branch 'feature_wall_wipe' 2016-11-07 11:37:18 +01:00
Ghostkeeper c4a3830838 Merge branch 'bugfix_support_brim_round' 2016-11-04 15:23:47 +01:00
Jaime van Kessel d546c27462 Merge branch 'master' of github.com:Ultimaker/CuraEngine 2016-11-04 14:59:57 +01:00
Jaime van Kessel 7664e81aa2 Merge branch 'feature_concentric_3d_infill' of github.com:Ultimaker/CuraEngine 2016-11-04 14:54:07 +01:00
Tim Kuipers aa2ce7c770 refactor: retrieve print_layer_count from SliceDataStore rather than passing it to all functions (CURA-2077) 2016-11-04 14:23:27 +01:00
Tim Kuipers f63fc1ed74 fix: compute layer_count once and for all (CURA-2077) 2016-11-04 14:18:47 +01:00
Tim Kuipers ac183f4e4b refactor: don't pass down total_layers, but use mesh.layers.size instead (CURA-2077) 2016-11-04 13:15:03 +01:00
Tim Kuipers 4f3c337cc7 fix: resize layers vector in all meshes beforehand (CURA-2077)
A lot of (outdated) code depends on there being the same amount of layers in each mesh.
This was not the case for anti-overhang meshes and support meshes
Now each mesh starts out with the same amount of empty layers
2016-11-04 13:14:23 +01:00
Ghostkeeper 1e24769061 Merge branch 'feature_start_layer_far_away' 2016-11-04 11:36:48 +01:00
Tim Kuipers 02134eb822 fix: don't retract while performing the outer wall wipe (CURA-1698) 2016-11-03 20:18:45 +01:00
Tim Kuipers b436da841a fix2: don't access protected member from within lambda function (CURA-2704) 2016-11-03 14:45:58 +01:00
Tim Kuipers fa95e56b76 fix: don't access protected member from within lambda function (CURA-2704) 2016-11-03 14:13:52 +01:00
Ghostkeeper 6bed19c295 Merge branch 'feature_infill_support' 2016-11-03 13:37:07 +01:00
Tim Kuipers 2a20853b92 fix: getExtrudersUsed only include platform adhesion for first layer(s) (CURA-2789) 2016-11-02 17:50:30 +01:00
Tim Kuipers 09ad6301e7 refactor: separate handleSupportBeforeModels out of FffGcodeWriter::addSupportToGCode (CURA-2789) 2016-11-02 16:55:34 +01:00
Tim Kuipers d8fa29e979 cleanup: const-correctness for SliceDataStorage::getExtrudersUsed (CURA-2789) 2016-11-02 16:54:50 +01:00
Tim Kuipers ab91cc2def lil refactor: p0 ==> b_from_transformed (CURA-2704)
to conform to the other parameters such as a_from_transformed
2016-11-02 16:39:31 +01:00
Tim Kuipers cd4e2e29a3 lil refactor: transformed_startPoint ==> transformed_from (CURA-2704) 2016-11-02 16:37:12 +01:00
Tim Kuipers 0f454e897b refactor: polygonCollidesWithlineSegment ==> polygonCollidesWithLineSegment (l==>L) (CURA-2704) 2016-11-02 16:35:33 +01:00
Tim Kuipers c1d53811f3 lil (no unneccesary type cast (CURA-2077) 2016-11-02 16:05:36 +01:00
Tim Kuipers dbe6269262 Revert "refactor: support_mesh ==> overhang_mesh (CURA-2077)"
This reverts commit 00041da2df.
2016-11-02 16:01:08 +01:00
Tim Kuipers 0c395c5bfa fix: wall wipe didn't update last point (CURA-1698) 2016-11-02 15:35:34 +01:00
Tim Kuipers f312f15813 Merge branch 'master' into feature_infill_support 2016-11-01 11:04:13 +01:00
Ghostkeeper 406ea7155c Merge pull request #408 from thopiekar/master-gcc6-fix
Adding <numeric> for GCC 6.x
2016-11-01 10:21:16 +01:00
Thomas Karl Pietrowski f0f23ed732 Adding <numeric> for GCC 6.x
Otherwise you will get something like:

In file included from /<<PKGBUILDDIR>>/src/FffPolygonGenerator.cpp:7:0:
/<<PKGBUILDDIR>>/src/utils/algorithm.h: In function ‘std::vector<long unsigned int> cura::order(const std::vector<_Tp>&)’:
/<<PKGBUILDDIR>>/src/utils/algorithm.h:30:5: error: ‘iota’ is not a member of ‘std’
     std::iota(order.begin(), order.end(), 0); // fill vector with 1, 2, 3,.. etc
     ^~~
2016-11-01 09:48:46 +01:00
Ghostkeeper 0a59a059f4 Merge branch 'feature_nozzle_off_after_use' 2016-10-31 13:31:37 +01:00
Tim Kuipers e902fb3fc9 lil (CURA-2704)
makes for better debugging of the scenario of doom (isinside =/= inside)
2016-10-27 22:55:20 +02:00
Tim Kuipers c7be93e850 test: isinside error I couldn't reproduce (CURA-2704) 2016-10-27 22:53:51 +02:00
Tim Kuipers fe8207fb1b fix: user clipper functions for Polygons::inside (CURA-2704) 2016-10-27 22:53:15 +02:00
Tim Kuipers d1fbe96d6f feat: use LocToLineGrid for moveInside-like functions (CURA-2704) 2016-10-27 17:17:07 +02:00
Tim Kuipers ccc89e6263 refactor: typedef SparseLineGrid<PolygonsPointIndex, PolygonsPointIndexSegmentLocator> LocToLineGrid (CURA-2704) 2016-10-27 16:28:41 +02:00
Tim Kuipers d235de6ca2 fix: early stopping for SparseGrid for_each-like functions (CURA-2704) 2016-10-27 15:06:54 +02:00
Tim Kuipers 4d98e07eb4 fix: safety for polygon operator[] (CURA-2704) 2016-10-27 12:22:50 +02:00
Tim Kuipers 7c3f69a5bf bugfixes: combing edge cases (CURA-2704) 2016-10-27 12:22:13 +02:00
Tim Kuipers 846bb1109a fix: combing: create inside_loc_to_line grid after partsView (CURA-2704) 2016-10-27 12:02:48 +02:00
Tim Kuipers 8c5ba49068 fix: more lenient assertions due to rounding errors (CURA-2704) 2016-10-26 18:33:14 +02:00
Tim Kuipers 8e18139ae9 fix: use loc_to_line_grid for optimized combpath optimization (CURA-2704) 2016-10-26 18:32:05 +02:00
Tim Kuipers 410d42ccb3 fix: use inside_loc_to_line grid for checking whether a small move crosses the boundary (CURA-2704) 2016-10-26 18:02:10 +02:00
Tim Kuipers 2c35ba595c refactor: use LazyInitialization for Comb::outside_loc_to_line (CURA-2704) 2016-10-26 17:53:34 +02:00
Tim Kuipers 8f04afbff9 refactor/fix: LazyInitialization: from bind to lambdas (CURA-2704)
also fixes the problem of temporary rvalues being used by the constructor function
2016-10-26 17:51:57 +02:00
Tim Kuipers 1fd5355290 fix: combing: compute whether a small move is cross-boundary (CURA-2704)
That is: whether the move is (party) over the in_between area
2016-10-26 15:43:59 +02:00
Tim Kuipers 65b6c48391 refactor: use LazyInitialization for Comb::boundary_outside (CURA-2704) 2016-10-26 15:41:16 +02:00
Tim Kuipers 34c0960cc2 fix: LazyInitialization constructor with function object (CURA-2704) 2016-10-26 15:39:41 +02:00
Tim Kuipers d6175e8269 feat: LazyInitialization (CURA-2704) 2016-10-26 15:38:42 +02:00
Thomas Karl Pietrowski 47984afb5f Fixing formatting in README.md 2016-10-25 20:08:49 +02:00
Tim Kuipers c86823033d feat: PolygonUtils::polygonCollidesWithlineSegment(.) for a loc_to_line_grid (CURA-2704) 2016-10-25 17:59:19 +02:00
Tim Kuipers 6c157b4e1f fix: made function parameters const in SparseGrid (CURA-2704) 2016-10-25 17:52:32 +02:00
Tim Kuipers 97b8d63547 fix: LinearAlg2D::lineSegmentsCollide now properly handles colinear cases (CURA-2704) 2016-10-25 16:58:28 +02:00
Tim Kuipers f0536be401 refactor: move part of LinearAlg2D::lineSegmentsCollide to LinearAlg2D (CURA-2704) 2016-10-25 16:56:57 +02:00
Tim Kuipers 2c983ce39c feat: SparseGrid::processLine (CURA-2704) 2016-10-25 16:04:38 +02:00
Tim Kuipers a3eb8ebb2d refactor: made SparseGrid function templates into std::function (CURA-2704) 2016-10-25 16:04:01 +02:00
Tim Kuipers bb98cb983e refactor: abstract SparseLineGrid::insert to SparseGrid::processLine (CURA-2704) 2016-10-25 11:56:17 +02:00
Tim Kuipers a67f7465c1 fix: print support consecutive instead of always at end of layer (CURA-2789)
also support_interface_extruder_nr mattered even if the interface was turned off
2016-10-22 16:34:02 +02:00
Tim Kuipers 9b8ef3981a feat: retract_at_layer_change (CURA-2780) 2016-10-22 16:21:20 +02:00
Tim Kuipers 24a22eec82 feat: start_layers_at_same_position (CURA-1112) 2016-10-21 17:45:44 +02:00
Ghostkeeper 4d34cbc66b Merge branch 'bugfix_double_to_stream' 2016-10-21 17:28:58 +02:00
Tim Kuipers 405a2b2a5f fix: allow outer wall wipe to wrap around as many times as requested (CURA-1698) 2016-10-21 17:08:09 +02:00
Tim Kuipers 17260b0272 feat: wall_0_wipe (CURA-1698) 2016-10-21 17:01:40 +02:00
Tim Kuipers 2785baf7be refactor: allow wall_0_wipe distance as parameter to GCodePlanner::addPolygon (CURA-1698) 2016-10-21 17:01:25 +02:00
Tim Kuipers c4bc6b8d19 cleanup: codestyle in GCodePlanner::addPolygon (CURA-1698) 2016-10-21 17:00:24 +02:00
Tim Kuipers a29af7f791 Revert "Revert "feat: setting for carveMultipleVolumes (CURA-2712)""
This reverts commit d50f67e583.

Reapplies b2d837efde
2016-10-21 16:22:45 +02:00
Tim Kuipers f304c09db4 Merge branch '2.3' 2016-10-21 16:22:30 +02:00
Tim Kuipers d50f67e583 Revert "feat: setting for carveMultipleVolumes (CURA-2712)"
This reverts commit b2d837efde.
2016-10-21 16:22:16 +02:00
Tim Kuipers b2d837efde feat: setting for carveMultipleVolumes (CURA-2712) 2016-10-21 16:05:15 +02:00
Ghostkeeper 5c680b312b Indent broken-up lines
So that you can see that the line is broken up into multiple lines.

Contributes to issue CURA-1103.
2016-10-21 15:52:22 +02:00
Ghostkeeper 0a683ff05e Transform order algorithm to our code style
Lukasz needs to obey the rulesz!

Contributes to issue CURA-1103.
2016-10-21 15:39:19 +02:00
Tim Kuipers 0dc6dcbb34 fix: concentric infill doesn't start right next to the inner wall any more (CURA-2772) 2016-10-20 23:22:07 +02:00
Tim Kuipers dbb48c82bf fix: concentric infill doesn't oscilate because of alternate extra wall (CURA-2772)
because the innermost wall was different every layer, the concentric infill was also shifted every layer
2016-10-20 23:13:57 +02:00
Tim Kuipers 2a1e4da930 feat: concentric 3d infill (CURA-2772) 2016-10-20 22:57:31 +02:00
Tim Kuipers dd481bcc2e fix: tetrahedral infill line distance is now the average line distance (CURA-2772)
Because the lines of tetrahedral infill sway toward and away from each other, we need to speak of an average line distance.
However, the line distance when you skip one line is constant; I call that the period.
2016-10-20 22:56:51 +02:00
Tim Kuipers f68d1a4e2d fix: concentric infill copied instead of pass by reference (CURA-2772) 2016-10-20 22:52:51 +02:00
Tim Kuipers 9d56baba41 fix: keep SliceMeshStorage aligned with Mesh (CURA-2077) 2016-10-20 09:38:25 +02:00
Tim Kuipers 4e96d9cbe6 feat: infill_hollow (CURA-2748) 2016-10-19 18:13:38 +02:00
Tim Kuipers 00041da2df refactor: support_mesh ==> overhang_mesh (CURA-2077) 2016-10-19 16:42:50 +02:00
Tim Kuipers 478bd31d02 Merge branch 'bugfix_double_to_stream' of github.com:Ultimaker/CuraEngine into bugfix_double_to_stream 2016-10-18 11:02:37 +02:00
Tim Kuipers faab907bab fix: int64_t and double formatting (CURA-2627) 2016-10-17 17:51:38 +02:00
Tim Kuipers dff554863c fix: nozzle was never turned off (CURA-1103) 2016-10-17 17:25:18 +02:00
Tim Kuipers f2222f97fd fix: PrimeTower::extruder_count wasn't set (CUTA-1103) 2016-10-17 17:20:25 +02:00
Tim Kuipers aa18e7bd08 feat: turn nozzle off after last layer switch (CUTA-1103) 2016-10-17 17:12:15 +02:00
Tim Kuipers 07dc53765a fix: removeEmptyFirstLayers invalidated mesh.layer_nr_max_filled_layer (CURA-1103) 2016-10-17 17:11:37 +02:00
Tim Kuipers 559deb8914 refactor: moved max_print_height_second_to_last_extruder to FffPolygonGenerator (CURA-1103) 2016-10-17 17:10:57 +02:00
Tim Kuipers 421ff6d818 feat: prime tower max print height calculation more generic (CURA-1103)
Also fix for platform adhesion in registering the max height an extruder is used.
2016-10-17 15:32:26 +02:00
Tim Kuipers e85a1004cd feat: algorithm::order function (CURA-1103) 2016-10-17 14:46:07 +02:00
Tim Kuipers 627848bc41 refactor: max_object_height_second_to_last_extruder ==> max_print_height_second_to_last_extruder (CURA-1103) 2016-10-17 11:30:53 +02:00
Ghostkeeper eccc62cf1d Add whitespace around binary operators
As per our code style.

Contributes to issue CURA-2627.
2016-10-17 11:06:22 +02:00
Tim Kuipers 1d251fef70 fix: limit prime tower height when support is touching buildplate only (CURA-2633) 2016-10-15 16:15:18 +02:00
Tim Kuipers 16a0cf0fd5 fix: make first layer brim under support round (CURA-2686) 2016-10-15 15:59:48 +02:00
Tim Kuipers 3c7c352bfc fix: add support during generation, causing all support settings to be applied to support meshes (CURA-2077)
This has the disadvantage that support meshes are re-evaluated for each normal mesh.
However, otherwise support meshes could overlap with each other mesh..
2016-10-14 16:44:50 +02:00
Tim Kuipers 66e6375942 fix: lil typo in AreaSupport::generateSupportAreas for support meshes (CURA-2077) 2016-10-14 16:43:26 +02:00
Tim Kuipers 8d3f66c2cb fix: don't switch extruder if support interface is too small to be printed (CURA-2077) 2016-10-14 16:41:15 +02:00
Tim Kuipers 1fd540c231 fix: also print support of support meshes above normal support (CURA-2077) 2016-10-14 16:00:45 +02:00
Tim Kuipers ac799dd00e fix: don't do multi volumes functions on support meshes (CURA-2077) 2016-10-14 16:00:22 +02:00
Tim Kuipers 699406b044 refactor: anti_support_mesh ==> anti_overhang_mesh (CURA-2077) 2016-10-14 15:31:53 +02:00
Tim Kuipers 2f3333e87c feat: anti support meshes (CURA-2077) 2016-10-14 15:30:19 +02:00
Tim Kuipers 58e2e1a4e1 fix: better buffer for double to stream and more tests (CURA-2627) 2016-10-13 17:39:59 +02:00
Tim Kuipers 4ebbceb3e3 Merge branch '2.3' 2016-10-11 16:43:05 +02:00
Tim Kuipers c0495edf48 fix: turn off fans if fans are disabled (CURA-2603) 2016-10-11 16:42:56 +02:00
Tim Kuipers ace0045109 Merge branch '2.3' 2016-10-11 16:14:44 +02:00
Tim Kuipers 1574292945 fix: forgot to write retractions with given precision (CURA-2619) 2016-10-11 16:14:01 +02:00
Tim Kuipers ed3f9f107c fix: only wipe on prime tower when enabled (CURA-2605) 2016-10-11 15:55:05 +02:00
Tim Kuipers 7a4a7fe46a Merge branch '2.3' 2016-10-11 15:01:03 +02:00
Tim Kuipers 18bf08a1b5 fix: retrieve adhesion_type globally (CURA-2605) 2016-10-11 15:00:51 +02:00
Tim Kuipers 977d02a9a2 Updated link to code conventions 2016-10-11 09:22:02 +02:00
Tim Kuipers f30c309249 Merge branch 'master' of github.com:Ultimaker/CuraEngine 2016-10-10 16:08:31 +02:00
Tim Kuipers af3536b307 Merge remote-tracking branch 'remotes/origin/feature_remove_trailing_zeros' 2016-10-10 16:08:22 +02:00
Tim Kuipers 8aed4c9139 Merge pull request #399 from Renha/master
Extra dollars removed from readme.
2016-10-10 15:48:30 +02:00
Renha 03fa1c2d37 Extra dollars removed from readme.
There are no need to write $s twice.
2016-10-10 16:40:49 +03:00
Tim Kuipers 7582100fba fix: force prime tower wipe as extrusion move so that it's not z hopped (CURA-2522) 2016-10-06 13:42:02 +02:00
Tim Kuipers edd1d5c8dd fix: possible infinite loop in support interface generation (CURA-2545) 2016-10-05 17:35:16 +02:00
Tim Kuipers 5971604805 cleanup: less boolean trappy (CURA-2525) 2016-10-05 17:20:48 +02:00
Tim Kuipers a8ea6511bd fix: Polygon::smooth_outward can now remove whole hole polygons (CURA-2526) 2016-10-05 14:28:39 +02:00
Tim Kuipers 5c1083db0b fix: dont remove support for brim inside empty holes (CURA-2525) 2016-10-04 15:43:04 +02:00
Tim Kuipers f9b917f9d1 feat: Polygons::getEmptyHoles (CURA-2525) 2016-10-04 15:42:40 +02:00
Tim Kuipers eb065c1a07 fix: avoid obstacles and retract when moving to prime tower (CURA-2522) 2016-10-04 14:16:06 +02:00
Jack Ha 29978b8654 Fix testsuite by adding mock resolveOrValue 2016-10-04 13:23:21 +02:00
Tim Kuipers 9563aeb1c0 fix: prime tower back to LINEs because of CURA-2511 (CURA-2510) 2016-10-03 17:10:46 +02:00
Ghostkeeper fb7cd6a572 Fix indenting
Contributes to issue CURA-1962.
2016-09-30 16:26:39 +02:00
Tim Kuipers 3f02cf1f33 Merge branch 'feature_rotation_matrix' of github.com:Ultimaker/CuraEngine into feature_rotation_matrix 2016-09-30 16:21:14 +02:00
Tim Kuipers 7bdd5690f7 fix: mesh_rotation renamed to mesh_rotation_matrix and warning emitted if matrix is incorrect (CURA-2416) 2016-09-30 16:20:45 +02:00
Tim Kuipers 1de4107ea6 refactor: also use my own << operator for writing integers to stream (CURA-1962) 2016-09-30 15:30:59 +02:00
Tim Kuipers 6306321007 lil fixes (CURA-1962) 2016-09-30 15:26:55 +02:00
Tim Kuipers 7281e2187e feat: faster double to stream without trailing zeros (CURA-1962) 2016-09-30 15:26:14 +02:00
Ghostkeeper 5f99281478 Fix setting name mesh_rotation_matrix
This was not congruent with the setting name in command_line_settings.def.json

Contributes to issue CURA-2416.
2016-09-30 14:00:17 +02:00
Tim Kuipers 3d3c12a9d2 feat: get transformation matrix from settings (CURA-2416) 2016-09-30 12:29:08 +02:00
Ghostkeeper 739aedf8ad Merge branch 'feature_wipe_on_prime_tower' 2016-09-29 20:46:00 +02:00
Tim Kuipers 1bb79f850a fix: no more wipe after last printed prime tower; no z hop for wipe; wipe slower (CURA-2420) 2016-09-29 18:30:25 +02:00
Tim Kuipers 3d77a426dd fix: only wipe on single closest line of prime tower (CURA-2420)
otherwise the move from the switch location to the wipe tower already wiped the nozzle on the prime tower, because it moved through the prime tower toward the wipe location
2016-09-29 15:03:41 +02:00
Arjen Hiemstra 3aa3e4ef92 Merge branch 'feature_export_speedup'
* feature_export_speedup:
  lil writeInt2mm improvements (CURA-2472)
  fix: output integers directly to stream rather than converting to double first (CURA-2472)
2016-09-29 13:32:34 +02:00
Tim Kuipers eb5231e7a8 lil fix: forgotten return statement in hopefully unreachable code (CURA-2420) 2016-09-29 12:16:53 +02:00
Tim Kuipers 17a9764181 fix: retrieve support_enable per mesh (CURA-2492) 2016-09-29 11:57:09 +02:00
Tim Kuipers 86e7dbf2b1 lil writeInt2mm improvements (CURA-2472) 2016-09-29 10:00:36 +02:00
Tim Kuipers ccaf8538d8 fix: multVolumes: merge overlap better with model (CURA-2427)
when models where directly adjacent, the overlap area wouldn't be merged with the model at all places because of rounding errors
2016-09-29 09:46:44 +02:00
Tim Kuipers a248662077 lil doc (CURA-2420) 2016-09-28 18:53:56 +02:00
Tim Kuipers fc28698479 fix: tests for PolygonUtils::spreadDots (CURA-2420) 2016-09-28 18:41:59 +02:00
Tim Kuipers 263bb3099b bugfixes PolygonUtils::spreadDots, segmentLength and PolygonsPointIndex (CURA-2420) 2016-09-28 18:41:30 +02:00
Tim Kuipers 25b83c9dda factored out PolygonUtils::spreadDots from PrimeTower::generateWipeLocations (CURA-2420) 2016-09-28 17:54:54 +02:00
Tim Kuipers 7025e5cea4 indent only (CURA-2420) 2016-09-28 17:24:57 +02:00
Tim Kuipers 183fc38ca9 refactor PrimeTower::generateWipeLocations (CURA-2420) 2016-09-28 17:24:38 +02:00
Tim Kuipers f4461ca41a feat: simple fuctions to find the nearest vert in polygons (CURA-2420) 2016-09-28 17:20:12 +02:00
Tim Kuipers 5ba9026632 factored PolygonsPointIndex out of PolygonUtils (CURA-2420) 2016-09-28 17:19:29 +02:00
Tim Kuipers 01ec0b847f lil (CURA-2420) 2016-09-28 16:40:04 +02:00
Tim Kuipers 9fe8796844 fix: generateMultipleVolumesOverlap wasn't applied (CURA-2427) 2016-09-28 15:47:11 +02:00
Tim Kuipers c554ec4178 fix: register horizontal expansion in the AABB of a mesh (CURA-2427) 2016-09-28 15:16:05 +02:00
Tim Kuipers dce8a4629f fix: output integers directly to stream rather than converting to double first (CURA-2472) 2016-09-28 11:32:25 +02:00
Tim Kuipers 10af83137b prime tower: changed from lines to zigzag infill (CURA-2420) 2016-09-27 12:05:14 +02:00
Tim Kuipers d45d00b441 fix: wipe tower overlapped with brim (CURA-2420) 2016-09-27 11:56:31 +02:00
Tim Kuipers b2abcbd7b4 refactor: move last_prime_tower_poly_printed inside PrimeTower class (CURA-2420) 2016-09-27 11:29:50 +02:00
Tim Kuipers 9c15d18cfb unfeat: remove setting prime_tower_dir_outward (CURA-2420) 2016-09-27 11:22:59 +02:00
Tim Kuipers 7122335a55 prime tower: cleanup, const correctness and documentation (CURA-2420) 2016-09-27 11:21:01 +02:00
Tim Kuipers b5b05c1894 lil cleanup (CURA-1062) 2016-09-22 20:51:16 +02:00
Tim Kuipers 8d6dd5ae8b fix: dont draw skirt through ooze/draft shield (CURA-1062) 2016-09-22 20:08:18 +02:00
Tim Kuipers 433c90617e fix: always wipe nozzle diagonally on wipe tower (CURA-2420) 2016-09-22 16:50:24 +02:00
Tim Kuipers 2980b20346 cleanup & documentation of primetower (CURA-2420) 2016-09-22 16:06:53 +02:00
Tim Kuipers 5993b5f606 oops committed debug code (CURA-2420) 2016-09-22 15:45:50 +02:00
Tim Kuipers f7940498f0 feat: wipe nozzle before starting prime tower (CURA-2420)
wipe at different locations each layer, so that there won't be a buildup of material on one place, which might get the tower knocked over
2016-09-22 15:42:58 +02:00
Tim Kuipers 03acc7629c made some polygon functions const as they should be (CURA-2420) 2016-09-22 15:41:46 +02:00
Ghostkeeper f903d438f2 Merge branch 'bugfixes_adhesion' 2016-09-22 13:53:47 +02:00
Tim Kuipers 04dc8ac68b lil auxiliary functions (CURA-2420) 2016-09-22 13:34:53 +02:00
Tim Kuipers 1a2ba63c74 lil cleanup (CURA-2420) 2016-09-21 18:03:11 +02:00
Tim Kuipers d28d86c208 doc: better documentation of limit_to_extruder property in the proto file (CURA-2308) 2016-09-21 17:59:55 +02:00
Tim Kuipers afd91bfd2e cleanup: remove old concentric and spiral prime tower (CURA-2420)
I think these prime towers only printed half of the space, assuming the other extruder would print the other half
2016-09-21 17:18:21 +02:00
Tim Kuipers 4cd55f0907 refactor: move wipePoint inside wipeTower (CURA-2420) 2016-09-21 16:55:56 +02:00
Tim Kuipers f20320031f fix: precision was inconsistent (CURA-1955) 2016-09-21 16:07:38 +02:00
Tim Kuipers 44f7b92958 some cleanup and const correctness (CURA-1062) 2016-09-21 10:45:11 +02:00
Tim Kuipers 0b4eda9592 fix: brim was slow for high poly dual extrusion models (CURA-1062, CURA-2422) 2016-09-20 18:12:01 +02:00
Tim Kuipers c674a84f38 Merge branch 'master' into bugfixes_adhesion 2016-09-20 17:31:55 +02:00
Tim Kuipers 2660bd1bc1 Merge branch 'totalretribution-reverse_inset_order' 2016-09-20 13:43:31 +02:00
Tim Kuipers 618660c16f Merge branch 'reverse_inset_order' of https://github.com/totalretribution/CuraEngine into totalretribution-reverse_inset_order 2016-09-20 13:35:25 +02:00
Tim Kuipers 252a797f36 fix: shield-brim got odd number of brim lines, causing gaps (CURA-1062) 2016-09-20 11:37:26 +02:00
Tim Kuipers 2db70b4b5c fix: put helper parts of initial layer in separate layer so as to not apply the layer_0_z_overlap (CURA-1062) 2016-09-20 11:13:09 +02:00
Tim Kuipers 379a3d54f1 fix: brim for ooze/draft shield (CURA-1062) 2016-09-20 09:57:46 +02:00
Tim Kuipers 92fca17411 fix: always even number of brim lines between support and model (CURA-1062) 2016-09-20 09:57:23 +02:00
Ghostkeeper 87637c9ef7 Fix comparison between long and int64_t
On some machines, long isn't 64-bit.

Contributes to issue CURA-2296.
2016-09-20 09:18:44 +02:00
Tim Kuipers d2bbe41ff1 refactor: generateSkirtBrim ==> SkirtBrim::generate CURA-1062) 2016-09-19 18:34:24 +02:00
Tim Kuipers a70fdfb917 feat: introduce layers with helper objects in the airgap (CURA-1062) 2016-09-19 18:01:35 +02:00
Tim Kuipers ceff626d87 raft auciliary functions (CURA-1062) 2016-09-19 17:46:33 +02:00
Tim Kuipers 53c4552de7 removed unused CommandSocket::sendLayerInfo (CURA-1062) 2016-09-19 17:39:08 +02:00
Ghostkeeper a576dd8929 Fix literal long on 32-bit
On some machines, this literal is only 32 bits wide.

I've now made it always 64 bits wide.

Contributes to issue CURA-2296.
2016-09-19 17:11:24 +02:00
Tim Kuipers dcec2d2584 refactor: generateRaft ==> Raft::generate (CURA-1062) 2016-09-19 16:31:58 +02:00
Tim Kuipers 6c2d7b72cb cleanup: removed unused param (CURA-1062) 2016-09-19 16:03:35 +02:00
Tim Kuipers 228b13c96c fix: raft base came half the line width too far (CURA-1062) 2016-09-19 15:54:40 +02:00
Tim Kuipers 4607d0a8ad fix: raft goes inward from draft/ooze shield and starts half a line width outward (CURA-1062) 2016-09-19 15:50:09 +02:00
Tim Kuipers cec7d2bef4 fix: make ooze shield offset round (CURA-1062)
so that the ooze shield can never fall outside of the build plate
2016-09-19 14:49:57 +02:00
Tim Kuipers 1eee21a16c fix: removeSmallAreas works on floats (CURA-1062) 2016-09-19 14:48:49 +02:00
Ghostkeeper e52beb8239 Fix warning of unused variable
It was used only in an assert, so if you're skipping asserts, the variable was unused. I've now cast it into the void to make it 'used'.
2016-09-19 14:40:37 +02:00
Ghostkeeper 72f09d3fa0 Merge bugfix_jagged_support
Conflicts:
	src/gcodeExport.cpp
	src/support.cpp
	src/utils/LinearAlg2D.cpp
	src/utils/linearAlg2D.h
	src/utils/polygon.cpp
2016-09-19 14:34:17 +02:00
Tim Kuipers 9ba3e301d6 fix: don't place ooze shield through thin areas; don't diagonalize oozze shield for too hgih angle; remove small areas afterwards (CURA-1062) 2016-09-19 14:25:34 +02:00
Ghostkeeper 4bea7d8ba2 Use unsigned long string interpreter
Sadly, stoui doesn't exist in C++11. We do have stoul though, which comes closer to what we intend and is still more powerful than we need.

Contributes to issue CURA-2314.
2016-09-16 17:03:08 +02:00
Ghostkeeper b03a7bd9ee Interpret cool_fan_full_layer as a layer number
Because it is.

Contributes to issue CURA-2314.
2016-09-16 16:43:06 +02:00
Ghostkeeper 1f5071c739 Add setting interpretation as layer number
Layer numbers are one-based and not negative. This translates it to zero-based.

Contributes to issue CURA-2314.
2016-09-16 16:41:44 +02:00
TotalRetribution a165265c0a Simplified outer_inset_first based on BagelOrb suggestion. 2016-09-16 10:34:53 +01:00
Ghostkeeper 7ba5b5c0c8 Merge branch 'bugfix_jagged_support' of github.com:Ultimaker/CuraEngine into bugfix_jagged_support 2016-09-15 16:12:22 +02:00
Tim Kuipers adcd061f00 fix: smooth_outward fixes (CURA-2296) 2016-09-15 15:39:13 +02:00
Tim Kuipers f6df79a134 sanity checks (CURA-2296) 2016-09-15 15:19:27 +02:00
Tim Kuipers 955399765c fix: smooth_outward: continue if a step in both directions doesn't violate the shortcut_length constraint (CURA-2296) 2016-09-15 15:07:30 +02:00
Tim Kuipers b79043f772 fix: smooth_outward: no more asserts which are violated by rounding errors (CURA-2296) 2016-09-15 14:42:27 +02:00
Tim Kuipers 1380d76075 Merge branch 'bugfix_jagged_support' of github.com:Ultimaker/CuraEngine into bugfix_jagged_support 2016-09-15 13:43:23 +02:00
Tim Kuipers a2c5a73f09 fix: support: prefer more smoothing rather than less (CURA-2296) 2016-09-15 13:10:41 +02:00
Tim Kuipers 1bdf07ae88 fix: support smoothing based on whether the current mesh has an interface (CURA-2296)
before it looked at all meshes
2016-09-15 13:06:51 +02:00
TotalRetribution ca1d6082e6 In processInsets moved code in for loops to processInsetLoop function to reduce duplication caused by outer_inset_first. 2016-09-15 12:06:02 +01:00
Tim Kuipers 33eabda16f refactor: support: limited support_line_width to somputation for smoothing_distance (CURA-2296) 2016-09-15 13:02:39 +02:00
TotalRetribution da659759cf Merge remote-tracking branch 'origin/master' into reverse_inset_order 2016-09-15 12:00:53 +01:00
Tim Kuipers 5b99143761 lil doc (CURA-2296) 2016-09-15 12:59:05 +02:00
Tim Kuipers dc92c1376c lil refactor (CURA-2296) 2016-09-15 12:32:01 +02:00
Tim Kuipers beaf71dfe8 lil optimization: pass down the square of shortcut_length in smooth_outward (CURA-2296) 2016-09-15 12:30:33 +02:00
Tim Kuipers 3062c07763 fix: smooth_outward used outdated v02 var (CURA-2296) 2016-09-15 12:23:53 +02:00
Tim Kuipers 134b37da2e refactor: factored out complex case out of smooth_outward (CURA-2296) 2016-09-15 12:15:12 +02:00
Tim Kuipers af10ef571d refactor: factor out the simple case from smooth_outward (CURA-2296) 2016-09-15 11:54:47 +02:00
Tim Kuipers 92af4b76b7 doc: more comments for smooth_outward (CURA-2296) 2016-09-15 10:25:58 +02:00
Tim Kuipers d97cfa4152 refactor: factor out inner part of loop in smoot_outward (CURA-2296) 2016-09-15 09:50:53 +02:00
Tim Kuipers 9988c67397 fix: invalid assert removed (CURA-2296)
assertion didn't hold for lines with a very shallow angle
2016-09-15 09:32:24 +02:00
Tim Kuipers b7f77e9dca lil improvement (CURA-2296) 2016-09-15 09:11:31 +02:00
Tim Kuipers ca25ce076c lil comment (CURA-2317) 2016-09-14 18:12:30 +02:00
TotalRetribution 71bfafbc0f Fixed Indentation in FffGcodeWriter.cpp FffGcodeWriter::processInsets. 2016-09-14 14:53:52 +01:00
Ghostkeeper ec44e711fb Fix long literals
Turns out the 1 wasn't an 1 but a lowercase L. This is why people tend to use uppercase L for long.

Contributes to issue CURA-2296.
2016-09-14 13:48:02 +02:00
Ghostkeeper 8fd5c6d404 Fix wording of angle parameter documentation
Maximal is a local maximum. Maximum is the actual maximum, where there is nothing higher. The second is correct here.

Contributes to issue CURA-2296.
2016-09-14 13:39:42 +02:00
Ghostkeeper 9da278795f Fixed numerical literal typo
Contributes to issue CURA-2296.
2016-09-14 13:33:39 +02:00
Ghostkeeper 2050e71dda Fixed numerical literal typo
Contributes to issue CURA-2296.
2016-09-14 13:30:48 +02:00
Tim Kuipers df003d7649 Merge branch 'master' of github.com:Ultimaker/CuraEngine 2016-09-14 10:47:17 +02:00
Tim Kuipers 281e647b82 refactor: global_inherits_stack ==> limit_to_extruder (CURA-2308) 2016-09-14 10:47:08 +02:00
Ghostkeeper 0771eafc60 Fix warning of comparison unsigned to signed
This now allows for higher amounts of draft shield layers, in theory, with the same memory and processing cost.
2016-09-13 17:20:14 +02:00
Ghostkeeper 0743994375 Add spaces after comma
As per the code style.

Contributes to issue CURA-2296.
2016-09-13 16:53:42 +02:00
Tim Kuipers 7b9e571474 fix: don't retrieve the machine name from the json document, but from the settings (CURA-2360) 2016-09-13 16:44:07 +02:00
Ghostkeeper 73506345ac Fix line direction mix-up in documentation
The point is before ab, or after ba.

Contributes to issue CURA-2296.
2016-09-13 16:39:52 +02:00
Tim Kuipers ff57c578db fix: copy first extruder if there's no definition for a latter one (CURA-2016) 2016-09-13 15:00:53 +02:00
TotalRetribution 0436916f4a Merge remote-tracking branch 'origin/master' into reverse_inset_order
Conflicts:
	src/FffGcodeWriter.cpp

Fixed Conflict with src/FffGcodeWriter.cpp
2016-09-13 10:55:31 +01:00
Tim Kuipers 4a392d1e79 fix: interface wasn't generated near the top of the print (CURA-2308) 2016-09-13 11:42:53 +02:00
Tim Kuipers eb277a1181 lil type fix (CURA-2016) 2016-09-13 11:38:09 +02:00
Tim Kuipers 7b972305b5 fix: exit when file couldn't load (CURA-2016) 2016-09-13 11:35:41 +02:00
Tim Kuipers 103b2ef7a8 Merge branch 'master' of github.com:Ultimaker/CuraEngine 2016-09-13 11:18:23 +02:00
Tim Kuipers a4bb8ed287 fix: exit when json couldn't load (CURA-2016) 2016-09-13 11:15:54 +02:00
Tim Kuipers 8edce9d470 log errors when json files couldn't load (CURA-2016) 2016-09-13 11:08:46 +02:00
Tim Kuipers 54152aded7 lil cleanup (CURA-2016) 2016-09-13 10:35:58 +02:00
Tim Kuipers 771e840d07 lil cleanup (CURA-2016) 2016-09-13 10:26:55 +02:00
Tim Kuipers 1057b1e277 fix: load extruder json when and only when extruder is created (CURA-2016) 2016-09-13 10:25:54 +02:00
Tim Kuipers 26b78d68f4 fix: don't overload extruder settings over user supplied (CURA-2016) 2016-09-12 18:30:39 +02:00
Tim Kuipers 2583c2e594 Revert "fix: command line slicing overwrote child settings with parent settings"
This reverts commit 9c2fb686e6.
2016-09-12 18:29:35 +02:00
Tim Kuipers 9c2fb686e6 fix: command line slicing overwrote child settings with parent settings 2016-09-12 18:08:08 +02:00
Tim Kuipers 7396deb65b fix: jerk gcode for repetier firmware 2016-09-12 11:07:53 +02:00
Tim Kuipers 32f234eb87 Merge branch '2.3' 2016-09-12 10:49:15 +02:00
Tim Kuipers adbf0354e6 refactor: getDraftShieldHeight==>getDraftShieldLayerCount (CURA-2098) 2016-09-12 10:49:00 +02:00
Tim Kuipers 5e7acc8b62 fix: draft shield is computed over all layers used now (CURA-2098) 2016-09-12 10:47:13 +02:00
Tim Kuipers b1044cbe24 lil innocent assert change 2016-09-09 17:19:16 +02:00
Tim Kuipers 91a5589413 Merge branch '2.3' 2016-09-09 17:04:50 +02:00
Tim Kuipers dc97b5f312 fix: add brim around support and around model (CURA-2317) 2016-09-09 12:30:04 +02:00
Tim Kuipers b494b7b86d fix: made secondary skirt generate even when the primary is empty; retrieved minimal_length per extruder (CURA-2308) 2016-09-09 12:10:38 +02:00
Tim Kuipers 970789fb4b lil renames (CURA-2308) 2016-09-09 11:45:18 +02:00
Tim Kuipers f4e19dd217 lil rename 2016-09-08 19:47:56 +02:00
Tim Kuipers 700ce8ef3b fix: retrieve interface_enable per mesh (CURA-2296) 2016-09-08 19:47:26 +02:00
Tim Kuipers df3426e8bb Merge branch '2.3' 2016-09-08 17:31:02 +02:00
Tim Kuipers fd73470580 fix: carveMultipleVolumes again! (CURA-1917) 2016-09-08 17:30:35 +02:00
Tim Kuipers 959664c080 Merge branch '2.3' 2016-09-08 17:17:53 +02:00
Tim Kuipers 3e9b42a2a2 fix: only print ooze shield up to the layer where the last extruder switch will happen (CURA-2139) 2016-09-08 17:17:44 +02:00
Tim Kuipers eb74c5ce88 Merge branch '2.3' 2016-09-08 16:24:47 +02:00
Tim Kuipers 51b840caee cleanup: made some stuff const in support.cpp (CURA-2052) 2016-09-08 16:24:34 +02:00
Tim Kuipers d695344f1b cleanup: removed debugging code (CURA-2296)
and removed acciodental bracket, which f*cks things up when you try to build previous commits
2016-09-08 15:44:52 +02:00
Tim Kuipers 0e9a7154ca removal: made support_area_smoothing hardcoded (CURA-2296) 2016-09-08 15:39:20 +02:00
Tim Kuipers 72e4bf8069 cleanup: some doc, parameter name changes, lil bugfix (CURA-2296) 2016-09-08 15:35:18 +02:00
Tim Kuipers acf26ba2f8 fix: made LinearAlg2D::getDist2FromLine more robust against rounding errors (CURA-2296) 2016-09-08 15:15:28 +02:00
Tim Kuipers 347f5c6238 fix: made LinearAlg2D::getPointOnLineWithDist more robust against rounding errors (CURA-2296) 2016-09-08 14:55:27 +02:00
Tim Kuipers aebe1ef46c fix: smooth_outward half blocked case was too naive (CURA-2296)
In the case which loks like \/ the sides may be longer than the shortcut on top, while there might be a shortcut halfway through which is long enough
2016-09-08 13:48:06 +02:00
Tim Kuipers 4f073ab23f fix: smooth_outward takes care of degenerate verts (CURA-2296) 2016-09-08 11:51:12 +02:00
Tim Kuipers 62dd1c1575 fix: smooth_outward now handles separately when v02 dist is about the required dist (CURA-2296)
This is to avoid rounding errors which conclude that no shortcut is possible
Now also in the general case
2016-09-08 11:18:50 +02:00
Tim Kuipers 04df283704 indent only (CURA-2296) 2016-09-08 10:46:47 +02:00
Tim Kuipers 695e5dd982 fix: smooth_outward now handles separately when v02 dist is about the required dist (CURA-2296)
This is to avoid rounding errors which conclude that no shortcut is possible
2016-09-08 10:45:18 +02:00
Tim Kuipers 26757ef802 fix: smooth_outward used degrees instead of radians (CURA-2296) 2016-09-07 19:40:01 +02:00
Tim Kuipers baf8f49360 feat: Polygon::smooth_outward (CURA-2296) 2016-09-07 19:23:27 +02:00
Tim Kuipers 4b20528a34 feat: LinearAlg2D::getPointOnLineWithDist(.) (CURA-2296) 2016-09-07 15:41:05 +02:00
Ghostkeeper 487b990f46 Merge branch '2.3' 2016-09-07 15:31:01 +02:00
Ghostkeeper 27d940191e Merge branch 'bugfix_polygon_oversimplification' into 2.3
Conflicts:
	src/utils/ListPolyIt.cpp
	src/utils/ListPolyIt.h
2016-09-07 15:29:05 +02:00
Ghostkeeper 7c48706e80 Fix compiler warning with multiline comment
Because the line ended in a backslash, it would take the next line as a comment too. The next line was already a comment, so it didn't matter, but this period is now at the end to prevent the compiler warning.

Contributes to issue CURA-1966.
2016-09-07 14:51:53 +02:00
Tim Kuipers 09a3ec4790 feat: LinearAlg2D::pointIsLeftOfLine(.) (CURA-2296) 2016-09-07 13:34:52 +02:00
Tim Kuipers b1e602f9f2 lil refactor: argument reorder in PolygonRef::smooth(.) (CURA-1966) 2016-09-07 09:21:11 +02:00
Tim Kuipers f98836c279 cleanup/optimization: PolygonRef::smooth has no more code duplication and values aren't recomputed any more (CURA-1966) 2016-09-07 09:17:43 +02:00
Tim Kuipers b54a0d3b91 fix: revamped Polygon smooth(.) (CURA-1966) 2016-09-06 17:43:27 +02:00
Jack Ha a3f2d08f13 Merge branch '2.3' 2016-09-06 16:53:22 +02:00
Ghostkeeper 2b6c70d19c Remove unnecessary brackets
Contributes to issue CURA-2052.
2016-09-06 15:14:51 +02:00
Tim Kuipers b79f362196 refactor: moves smooth(.) from Polygon.h to Polygon.cpp (CURA-1966) 2016-09-06 14:25:52 +02:00
Tim Kuipers 535bb8cf66 Merge branch '2.3' 2016-09-06 11:14:53 +02:00
Tim Kuipers eb2d4d3ad1 fix: test SparseLineGrid through origin and visualize correct 2016-09-06 11:12:35 +02:00
Tim Kuipers a8152bb727 Merge branch '2.3' into markwal-negativesparselinegrid 2016-09-06 10:55:11 +02:00
Tim Kuipers 3e0a2ca48a Merge branch 'master' of github.com:Ultimaker/CuraEngine 2016-09-06 10:54:25 +02:00
Tim Kuipers 2dc4411702 fix: help didn't get outputted 2016-09-06 10:54:18 +02:00
Mark Walker 0d38105a1a Simplify since we don't need the locals outside of
inner block any more
2016-09-05 11:30:40 -07:00
Mark Walker c179d16a9e sign to nonzero_sign and remove corner crossing fix 2016-09-05 11:14:03 -07:00
Mark Walker 76ac083eb3 Add some variable comments 2016-09-05 10:37:10 -07:00
Mark Walker da998384f0 SparseGridLine for negative coordinates
and also the TODO for precisely crossing cell corners
2016-09-05 10:37:10 -07:00
Tim Kuipers 13f7e0d7e4 fix: give support interface a different color (CURA-2049) 2016-09-05 18:01:21 +02:00
Tim Kuipers 1f721a2513 fix: expand support interface so that it's never too thin to be printed (CURA-2052) 2016-09-05 17:50:37 +02:00
Tim Kuipers 4df0a27cb2 fix: support interface skip layer flaw (CURA-2052)
we should divide up the remaining layers after we have checked the top or bottom most
2016-09-05 17:49:34 +02:00
Tim Kuipers 0c6aca19aa fix: interface also checks in-between layers for model (CURA-2052) 2016-09-05 17:05:17 +02:00
Aldo Hoeben bd8c501dc3 Update Cura.proto
Add polygon type for Support Interface

CURA-2049
2016-09-05 16:33:45 +02:00
Tim Kuipers b36acb07c5 fix: don't put skirt under support (CURA-2264) 2016-09-05 16:14:38 +02:00
Tim Kuipers 492bf72ffd fix: wire printing: processStartingCode copied from FffGcodeWriter and replaced setting retrieval to naive approach (CURA-1555) 2016-09-05 15:38:18 +02:00
Tim Kuipers f7ef517f01 fix: div by zero in LinePolygonsCrossings::lineSegmentCollidesWithBoundary() (CURA-2237) 2016-09-05 13:50:06 +02:00
Tim Kuipers 7a015ea146 fix: combing could cross exactly between two consectuive line segments of the boundary (CURA-2237) 2016-09-01 19:15:35 +02:00
Tim Kuipers 48aaebc20d fix: only set support.generates when it actually generated support (CURA-1571) 2016-09-01 18:03:02 +02:00
Tim Kuipers 209f770cf4 fix: don't drop on buildplate when there's support under the model (CURA-1571) 2016-09-01 18:02:01 +02:00
Tim Kuipers ec6c1216f2 fix: wireprint skirt extrusion was 10x too big (CURA-1555) 2016-09-01 15:04:29 +02:00
Tim Kuipers c638ca822b fix: wireprint flow now calculated as mm3 instead of E steps (CURA-1555) 2016-09-01 15:03:59 +02:00
Tim Kuipers 9007e3ff50 refactor: extrusion_per_mm ==> extrusion_mm3_per_mm (CURA-1555) 2016-09-01 15:01:25 +02:00
Tim Kuipers 32ce5e5a44 fix: wireprint don't print skirt at z0 (CURA-1555) 2016-09-01 14:57:29 +02:00
Tim Kuipers 825882100f fix: wire printing pointer bug (CURA-1555) 2016-09-01 13:47:32 +02:00
Tim Kuipers a47aa1e4fd cleanup: changed some logError to log or logWarning and cleaned up the messages 2016-09-01 13:06:01 +02:00
Tim Kuipers f5f1886175 feat: outputing correct gcode header after command line slicing 2016-09-01 12:02:27 +02:00
Tim Kuipers 26d05dc5e6 Merge pull request #385 from markwal/fixconstexprwarning
Fix constexpr function warning for C++14
2016-08-31 17:16:22 +02:00
Mark Walker 2715599791 Fix constexpr function warning for C++14
See https://akrzemi1.wordpress.com/2013/06/20/constexpr-function-is-not-const/
2016-08-28 20:51:36 -07:00
Jaime van Kessel 3c6b153e60 Removed double indication as this caused mac build to fail 2016-08-19 14:58:43 +02:00
Ghostkeeper 9bfdeb4ccd Move per-path offset to use it only on skirt
This is the only place where an outside offset is done and the inside polygons don't matter, so it is the only place where the union can safely be performed, since the union treats holes as normal polygons.

Contributes to issue CURA-2088.
2016-08-19 11:11:10 +02:00
Ghostkeeper 3aaddb08ba Move approxConvexHull implementation to CPP file
Where it damn well belongs, the little runt.

Contributes to issue CURA-2088.
2016-08-19 11:01:20 +02:00
Ghostkeeper 752985c9b2 Remove debug include
Because this include is at the top of the file, I didn't see it was still there. Sorry.

Contributes to issue CURA-2088.
2016-08-18 14:22:22 +02:00
Ghostkeeper dcb8a03a73 Offset polygons one path at a time
This prevents an infinite loop in the offset code in Clipper if the polygons overlap.

Contributes to issue CURA-2088.
2016-08-18 14:16:57 +02:00
Ghostkeeper 028c408be3 Move Polygons::Offset to CPP file
We should really do this with all of these functions. In this case, I required this in order to be able to import SVG for a bit of debugging.

Contributes to issue CURA-2088.
2016-08-18 13:21:27 +02:00
Ghostkeeper 822a2d55f2 Rebase bugfix_overlap_compensation onto master
Contributes to issue CURA-1911.
2016-08-17 17:09:21 +02:00
Ghostkeeper 3e283a375e Revert "lil feat: LinearAlg2D::projectPointOnLine(.) (CURA-1911)"
This reverts commit 7f08d37408eb9d010a24095f3f9b6facbe862c2e.

Contributes to issue CURA-1911.
2016-08-17 16:43:09 +02:00
Ghostkeeper 635ef25030 Optimize if-statement structure
Also more readable, in my opinion. It's just a bunch of cases and a base case, with lazy evaluation in between.

Contributes to issue CURA-1911.
2016-08-17 16:43:09 +02:00
Ghostkeeper 9a9855c0a5 Swap ifs so that we use else-if instead of recompute
Saves some computation time.

Contributes to issue CURA-1911.
2016-08-17 16:43:09 +02:00
Ghostkeeper 83e52f6e53 Make projections constant
These variables aren't changed. This might allow for better optimisations by the compiler.

Contributes to issue CURA-1911.
2016-08-17 16:43:09 +02:00
Ghostkeeper 9d59dde760 Improve overlap estimation for stair-case
In the case of stairs, there is no overlap either. The approximation now takes that into account at hardly any additional computational cost.

Contributes to issue CURA-1911.
2016-08-17 16:43:09 +02:00
Ghostkeeper 9b40d6053c Switch from and to back
Since these parameters are now renamed, this is clearer.

Contributes to issue CURA-1911.
2016-08-17 16:43:09 +02:00
Ghostkeeper ba05f42c91 Remove intermediary variable
The intermediary variable was supposed to make the variable name more clear. Instead, I just renamed the input parameter, removing the weird construct.

Contributes to issue CURA-1911.
2016-08-17 16:43:09 +02:00
Ghostkeeper 5684a0cbb4 Remove commented code
As per our code style.

Contributes to issue CURA-1911.
2016-08-17 16:43:09 +02:00
Ghostkeeper 0647fa21fe Switch to and from other parameters
For consistency.

Contributes to issue CURA-1911.
2016-08-17 16:43:09 +02:00
Ghostkeeper cb5467d2b3 Fix typo in documentation
Contributes to issue CURA-1911.
2016-08-17 16:43:09 +02:00
Ghostkeeper 24ec8bb254 Fix spelling in documentation
Contributes to issue CURA-1911.
2016-08-17 16:43:09 +02:00
Tim Kuipers 8069aba0b5 fix: proximity: don't disregard potential linking between a point and a consecutive line segment (CURA-1911)
short line segments might need linking from front to end when the previous and next line segment are parallel
2016-08-17 16:43:09 +02:00
Tim Kuipers 591cd105b5 lil TODO idea (CURA-1911) 2016-08-17 16:43:09 +02:00
Tim Kuipers 13e5e786bc fix: proximity: don't disregard potential linking between consecutive line segments (CURA-1911)
the end point of the new line segment might still need to be projected onto the other line segment
short line segments might need linking from front to end when the previous and next line segment are parallel
2016-08-17 16:43:09 +02:00
Tim Kuipers 6f0ef96c5e fix: small fixes for overlap compensation (CURA-1911) 2016-08-17 16:43:08 +02:00
Tim Kuipers ed636f9a44 lil assert change 2016-08-17 16:43:08 +02:00
Tim Kuipers 8f50db989c fix: remove degenerate verts which result in multiple verts sharing the same location (CURA-1911) 2016-08-17 16:43:08 +02:00
Tim Kuipers f4e22ae7a0 lil feat: LinearAlg2D::projectPointOnLine(.) (CURA-1911) 2016-08-17 16:43:08 +02:00
Tim Kuipers cbc6e6f270 fix: PolygonProximityLinker::addProximityEnding don't add to the same set we are looping over (CURA-1911) 2016-08-17 16:43:08 +02:00
Tim Kuipers 07b8165d47 fix: getApproxOverlapArea had arguments ordered wrong (CURA-1911) 2016-08-17 16:43:08 +02:00
Tim Kuipers e2409148cc fix: compute less overlap when line segments are not opposite each other (CURA-1911) 2016-08-17 16:43:08 +02:00
Tim Kuipers a3129bf1f6 feat: LinearAlg2D::pointIsProjectedBeyondLine (CURA-1911) 2016-08-17 16:43:08 +02:00
Tim Kuipers f191497234 fix: overlap compensation: move direction info down to getApproxOverlapArea (CURA-1911) 2016-08-17 16:43:08 +02:00
Tim Kuipers ef9c477ee2 lil cleanup & doc (CURA-1911) 2016-08-17 16:43:08 +02:00
Tim Kuipers bdcaa6c9ac lil refactor (CURA-1911) 2016-08-17 16:43:07 +02:00
Tim Kuipers 046310efcb more doc of PolygonProximityLinker::addNewPolyPoint (CURA-1911) 2016-08-17 16:43:07 +02:00
Tim Kuipers 74133ae7d7 rename PolygonProximityLinker::findProximatePoints a_from ==> a_point (CURA-1911) 2016-08-17 16:43:07 +02:00
Tim Kuipers 20dff1fe8b Revert "lil doc fix (CURA-1911)"
This reverts commit 1651e04f2cd1cfd69c8c92d397abfba53cb5dcc9.
2016-08-17 16:43:07 +02:00
Tim Kuipers c7be6e147b fix: was taking std::max of double and float (CURA-1911) 2016-08-17 16:43:07 +02:00
Tim Kuipers 574739e193 lil doc fix (CURA-1911) 2016-08-17 16:43:07 +02:00
Tim Kuipers b3c0f0d2da lil rewrite (CURA-1911) 2016-08-17 16:43:07 +02:00
Tim Kuipers 33be01596c lil doc of wall overlap (CURA-1911) 2016-08-17 16:43:07 +02:00
Tim Kuipers 2cbd6d1c8a lil rename in wall overlap (CURA-1911) 2016-08-17 16:43:07 +02:00
Tim Kuipers 510c328127 lil refactor: user unordered_map/set.find(.) rather than .count(.) (CURA-1911) 2016-08-17 16:43:06 +02:00
Ghostkeeper 9413aceaf2 Add space after comma
Thus haveth the code style spoken.

Contributes to issue CURA-1911.
2016-08-17 16:43:06 +02:00
Ghostkeeper aee1887b57 Add spaces around assignment operators
As the code style declares.

Contributes to issue CURA-1911.
2016-08-17 16:43:06 +02:00
Ghostkeeper b72917305c Add missing brackets
To comply to the code style.

Contributes to issue CURA-1911.
2016-08-17 16:43:06 +02:00
Ghostkeeper 7d61f00b3a Fix documentation grammar
It was hard to read due to the point A vs. the indefinite article a.

Contributes to issue CURA-1911.
2016-08-17 16:43:06 +02:00
Tim Kuipers 247f5d3cde fix: removed debugging member from WallOverlapComputation (CURA-1911) 2016-08-17 16:43:06 +02:00
Tim Kuipers 21202c2e8c fix: don't compensate for overlap if the two lines are going in the same direction (CURA-1911) 2016-08-17 16:43:06 +02:00
Tim Kuipers 6973e99cd1 cleanup: removed old slow overlap computation (CURA-1911) 2016-08-17 16:43:06 +02:00
Tim Kuipers 8cf1f1646b safety: check for duplicate points in input polygon (CURA-1911) 2016-08-17 16:43:06 +02:00
Tim Kuipers 2a1fc8245a safety: check for duplicate points in input polygon (CURA-1911) 2016-08-17 16:43:06 +02:00
Tim Kuipers a1a3931f68 feat: improved slicing speed by letting overlap compensation use SparseLineGrid (CURA-1911)
also iterate over the newly introduced points again, because they might need links which don't get introduced when we already passed that point in the poly
also prevert newly introduced points to again introduce new points, cause otherwise we might introduce a lot of new points in a corner (visual explanation in code)
2016-08-17 16:43:05 +02:00
Tim Kuipers e3dd8f0bdf forgotten import (CURA-1911) 2016-08-17 16:43:05 +02:00
Tim Kuipers 3a06f49fba fix: fixes for SparseLineGrid line to pixel algorithm (CURA-1911)
sometimes a line wouldn't be added to the grid at all
2016-08-17 16:43:05 +02:00
Tim Kuipers 65e90d5de0 feat: ListPolyIt operator!= and hash function object (CURA-1911) 2016-08-17 16:43:05 +02:00
Tim Kuipers e33c441f6d feat: Polygons::pointCount (CURA-1911) 2016-08-17 16:43:05 +02:00
Tim Kuipers 418de5d822 refactor: use actual SparseLineGrid rather than the hacked locToLineGrid (CURA-1911) 2016-08-17 16:43:05 +02:00
Tim Kuipers a6b45b683e fix: no more overlap areas are skipped because neighboring overlap areas were already processed (CURA-1911) 2016-08-17 16:43:05 +02:00
Tim Kuipers eda2c987ff feat: symmetric pair utility class (CURA-1911) 2016-08-17 16:43:04 +02:00
Tim Kuipers a71c18a146 safety: debug check for line grids (CURA-1911) 2016-08-17 16:43:04 +02:00
Tim Kuipers 424e3edb4d fix: SparseLineGrid computes cells based on print coords rather than grid coords (CURA-1911)
also a fix for horizontal lines, which caused division by zero.
2016-08-17 16:43:04 +02:00
Tim Kuipers ad1c442c9a feat: SparseLineGrid (CURA-1911) 2016-08-17 16:43:04 +02:00
Tim Kuipers 65ced4a4bb feat: SparseGrid now exposes more functions for grid to print space coords to inheriting classes (CURA-1911) 2016-08-17 16:43:04 +02:00
Tim Kuipers 242e8118e3 refactor: split off SparseGrid from SparsePointGrid (CURA-1911) 2016-08-17 16:43:04 +02:00
Tim Kuipers f720cc1f0b refactor: SparseGridInvasive ==> SparsePointGrid (CURA-1911) 2016-08-17 16:43:04 +02:00
Tim Kuipers 721d7d799f refactor: SparseGrid ==> SparsePointGridInclusive (CURA-1911) 2016-08-17 16:43:04 +02:00
Tim Kuipers 26c3a35150 fix: moved SparseGridElem to SparseGrid.h (CURA-1911) 2016-08-17 16:43:04 +02:00
Tim Kuipers c1d097f7fe lil rename (CURA-1911) 2016-08-17 16:43:04 +02:00
Tim Kuipers fedcfe582e safety: asserts in PolygonProximityLinker (CURA-1911) 2016-08-17 16:43:04 +02:00
Tim Kuipers 1ffafd4b17 debug fix: don't visualize SVG upside down (CURA-1911) 2016-08-17 16:43:03 +02:00
Tim Kuipers 45c4e2e0a1 fix: proximitylinker: don't add points twice (CURA-1911) 2016-08-17 16:43:03 +02:00
Tim Kuipers 6ae7fdac5c fix: proximitylinker: don't add points on the same location as other points (CURA-1911) 2016-08-17 16:43:03 +02:00
Tim Kuipers bf2123b82c feat/refactor: PolygonProximityLinker::addCornerLink (CURA-1911) 2016-08-17 16:43:03 +02:00
Tim Kuipers 81881a876d fix: link points ifthey are proximate even though the line segments are connected (CURA-1911) 2016-08-17 16:43:03 +02:00
Tim Kuipers 34859670ef refactor: bit of renaming (CURA-1911) 2016-08-17 16:43:03 +02:00
Tim Kuipers 4038d39e85 fix: process sharp corners before normal proximite points (CURA-1911) 2016-08-17 16:43:03 +02:00
Tim Kuipers 999a131ecf fix: ListPolyIt assignment overwrite referred polygon (CURA-1911) 2016-08-17 16:43:03 +02:00
Tim Kuipers 2bcffaa0ab fix: overlap comensation is now also activated for sharp corners (CURA-1911) 2016-08-17 16:43:03 +02:00
Tim Kuipers 7f584c2e4f refactor: merge proximity_point_links_endings into proximity_point_links (CURA-1911) 2016-08-17 16:43:03 +02:00
Tim Kuipers ba045e803b indent change only (CURA-1911) 2016-08-17 16:43:03 +02:00
Tim Kuipers 1fd2c66ec7 fix: don't create ending link when other side continues to overlap with the same point (CURA-1911)
also inverted some logic; indent change follows
2016-08-17 16:43:03 +02:00
Tim Kuipers be7ea53325 fix: account for overlap areas ending in a pointy end (CURA-1911) 2016-08-17 16:43:03 +02:00
Tim Kuipers 8045fb49ff refactor: let PolygonProximityLinker::findProximatePoints use ListPolyIt instead of separate iterators and references (CURA-1911) 2016-08-17 16:43:03 +02:00
Tim Kuipers 1504e38c8c fix: proximity was only recorded between points and line segments further on in the polygon (CURA-1911) 2016-08-17 16:43:03 +02:00
Tim Kuipers b646e94880 refactor: renaming in PolygonProximityLinker::findProximatePoints (CURA-1911) 2016-08-17 16:43:02 +02:00
Tim Kuipers 929719ebdd refactor: findProximatePoints actual linking functionality moved to its own function (CURA-1911) 2016-08-17 16:43:02 +02:00
Tim Kuipers 905d788c3c fix: findProximatePoints used wrong first segment (CURA-1911) 2016-08-17 16:43:02 +02:00
Tim Kuipers 0dba144c37 doc: PolygonProximityLinker overlap ==> proximity (CURA-1911) 2016-08-17 16:43:02 +02:00
Tim Kuipers f7ba6979da refactor: moved SparseGridInvasive to its own file (CURA-1911) 2016-08-17 16:43:02 +02:00
Tim Kuipers ae832cba68 fix: overlap links got introduced twice sometimes (CURA-1911) 2016-08-17 16:43:02 +02:00
Tim Kuipers 6bdc8dae51 refactor: factored out ProximityPointLink into ints own class file (CURA-1911) 2016-08-17 16:43:02 +02:00
Tim Kuipers 9a23163564 copyright 2016-08-17 16:43:02 +02:00
Tim Kuipers fcc207ad0d fix: store whether an overlap link is passed once outside of the link (CURA-1911)
The link was stored at multiple places (copies), so the information was not shared between all copies.
2016-08-17 16:43:02 +02:00
Tim Kuipers 44df11bc2c fix: PolygonProximityLinker::getLink now returns pointer instead of optionally a copy (CURA-1911) 2016-08-17 16:43:02 +02:00
Tim Kuipers 2458a9a580 lil optimization for wall overlap compensation (CURA-1911) 2016-08-17 16:43:02 +02:00
Tim Kuipers ba92bf9693 cleanup: PolygonProximityLinker::isLinked(.) makes wallOverlap more simple (CURA-1911) 2016-08-17 16:43:02 +02:00
Tim Kuipers 8c1ecf1200 cleanup: simplified WallOverlapComputation::handlePotentialOverlap (CURA-1911) 2016-08-17 16:43:02 +02:00
Tim Kuipers 4fdcf4ed29 cleanup: removed code duplication and add more documentation (CURA-1911) 2016-08-17 16:43:02 +02:00
Tim Kuipers cde315109a fix: overlap compensation now also compensates segments overlapping with points (CURA-1911) 2016-08-17 16:43:02 +02:00
Tim Kuipers 50ca8d7473 fix: let overlap compensation account for segments overlapping with multiple other segments (CURA-1911)
Make PolygONProximityLinker::Point2Link be a multimap, mapping points to multiple links
Change getLink(.) to getLinks(.)
Expose Point2Link so that outside classes can reason about which link is which

wallOverlap
Compute the actual overlapping area, since the ratio cannot easily be computed when multiple overlaps are involved
Compute the overlap area for segments for which both ends are linked to the same point
2016-08-17 16:43:02 +02:00
Tim Kuipers 9b8b3d150c cleanup: the list_polygons are used after the contructor of PolygonProximityLinker (CURA-1911) 2016-08-17 16:43:02 +02:00
Tim Kuipers f4fd6ab0f4 cleanup: lil doc and trailing whitespace (CURA-1911) 2016-08-17 16:43:02 +02:00
Tim Kuipers b593331c17 cleanup: removed outcommented debug code (CURA-1640) 2016-08-17 16:43:02 +02:00
Tim Kuipers afb6237cbf dox fix: updated doc of WallOverlap (CURA-1640) 2016-08-17 16:43:02 +02:00
Tim Kuipers a716b88621 dox fix: updated doc of PolygonProximityLinker (CURA-1640) 2016-08-17 16:43:02 +02:00
Tim Kuipers 0bc384c807 cleanup: removed unused commented code (CURA-1640) 2016-08-17 16:43:02 +02:00
Tim Kuipers a2e4f2a1cb fix: accidentally removed line (CURA-654) 2016-08-17 16:43:01 +02:00
Tim Kuipers d3c62049eb refactor: made WallOverlap use PolygonProximityLinker (CURA-654) 2016-08-17 16:43:00 +02:00
Tim Kuipers e773029266 refactor+fix: moved ProximityLinkAttributes into (mutable) ProximityLink + fixed iterator invalidation issues (CURA-654)
the [passed] attribute needs to be mutable: it doesn't change the hash of the object and needs to be changed after it's been in the set

fixed iterator invalidation issues by simply copying items from the set into the map, rather than referring to them
2016-08-17 16:39:35 +02:00
Tim Kuipers c42b3322cd removed debug function 2016-08-17 16:39:35 +02:00
Tim Kuipers b652db33c1 refactor: rename WallOverlap ==> Proximity (CURA-654) 2016-08-17 16:39:35 +02:00
Tim Kuipers 596082dc7c cleanup PolygonProximityLinker and use ListPolyIt (CURA-654) 2016-08-17 16:39:35 +02:00
Tim Kuipers 411300e0e1 refactor: factor out ListPolyIt class (CURA-654) 2016-08-17 16:39:35 +02:00
Tim Kuipers b44116c4e5 feat: PolygonProximityLinker class (CURA-654) 2016-08-17 16:39:35 +02:00
Ghostkeeper bf0cd02928 Merge branch 'master' of github.com:Ultimaker/CuraEngine 2016-08-11 16:37:53 +02:00
Ghostkeeper 3b4c54839d Merge feature_brim_under_support
Conflicts:
	src/SkirtBrim.cpp
	src/gcodeExport.cpp
2016-08-11 16:35:27 +02:00
Tim Kuipers b6cb7cd271 fix: don't limit speeds to 1 mm/s when retrieving a setting (CURA-1049) 2016-08-11 16:29:25 +02:00
Tim Kuipers ee447a9191 merge conflict fix (CUYRA-1956) 2016-08-11 16:22:31 +02:00
Ghostkeeper 9d755211cd Update reference to support skin
This new code was introduced by the brim-only-outside feature and gave no merge conflict, but was not up-to-date with the support roof rename to support skin.

Contributes to issue CURA-1413.
2016-08-11 15:58:46 +02:00
Tim Kuipers db83fcd57e fix: also generate brim for parts which flly lie inside other parts (CURA-1413) 2016-08-11 15:38:17 +02:00
Tim Kuipers 2ccaef10b9 feat: Polygons::removeEmptyHoles() (CURA-1413) 2016-08-11 15:38:17 +02:00
Tim Kuipers d004c77106 feat: brim only for outside polygons (CURA-1413) 2016-08-11 15:38:17 +02:00
Tim Kuipers 2bddfcd42a feat: Polygons::getOutsidePolygons() (CURA-1413) 2016-08-11 15:38:17 +02:00
Tim Kuipers 4cd1b5066c fix: only generate skirt polygons for used extruders (CURA-1647)
also cleaned up generateSkirtBrim a bit
also applied code conventions
inadvertently also causes support not to be removed by unprinted skirt
removed skirts_or_brims which didn't need to be a vector (only last elem was used)
2016-08-11 15:38:17 +02:00
Tim Kuipers e0959e4aa0 feat: ExtruderTrain::is_used (CURA-1647) 2016-08-11 15:38:17 +02:00
Tim Kuipers a29dcb33da fix: brim removed support rather than going around it (CURA-1647) 2016-08-11 15:24:20 +02:00
Tim Kuipers 152cf5835f Merge branch 'master' into feature_brim_under_support 2016-08-11 15:19:20 +02:00
Tim Kuipers eb065aa415 lil 2016-08-11 14:53:28 +02:00
Tim Kuipers 9430432af7 fix: support simplifies based on line width (CURA-1966) 2016-08-10 14:17:48 +02:00
Tim Kuipers 252c2cae28 assert fix: default jedi profile has speeds up to 200 2016-08-10 13:12:27 +02:00
Aldo Hoeben 9ee30bba12 Merge pull request #379 from Ultimaker/master-CURA-1724
CURA-1724: Updating README.md
2016-08-10 12:45:03 +02:00
Tim Kuipers 3afef5d29f fix: PolygonRef::simplify early catch for duplicate points in polygons (CURA-1966) 2016-08-10 12:01:48 +02:00
Tim Kuipers 056240d55c fix: PolygonRef::simplify prev wasn't recorded correctly (CURA-1966) 2016-08-10 11:59:28 +02:00
Tim Kuipers 10b43fc9f8 lil: AABB for single polygon (CURA-1966) 2016-08-10 11:37:44 +02:00
Tim Kuipers f83fbfe143 fix: PolygonRef::simplify only removes verts if BOTH line segments are too small now (CURA-1966) 2016-08-09 17:46:10 +02:00
Thomas Karl Pietrowski bcfe400c18 Correcting formatting 2016-08-09 17:38:37 +02:00
Tim Kuipers b67b51ce76 fix: overhauled PolygonRef::simplify (CURA-1966)
polygons would be simplified such that previously removed points violated the allowed error constraint further on in the algorithm
2016-08-09 17:37:10 +02:00
Tim Kuipers 83aeb36bcf feat: ListPolyIt convert functions for single (list)polygon (CURA-1966) 2016-08-09 17:34:00 +02:00
Thomas Karl Pietrowski e75cdf3f7c Removing hack for skipping build of protobuf using gtest
Can't find anything except of gmock in https://github.com/google/protobuf/blob/e8ae137c96444ea313485ed1118c5e43b2099cf1/autogen.sh that mentions gtest.
For about a year gmock has been moved to gtest, but 3.0.0 is still using gmock from it's old repository.
Additionally as the lines mentioned don't fit to the content of automake.sh, I just removed this part.
2016-08-09 17:21:21 +02:00
Thomas Karl Pietrowski ecd11212f4 Referencing to download page 2016-08-09 17:14:07 +02:00
Thomas Karl Pietrowski 5763b1704f Update README.md 2016-08-09 17:01:51 +02:00
Jack Ha f14d67934d Added some mock locals functions in runtests. CURA-1828. 2016-08-09 15:28:57 +02:00
Tim Kuipers 9ef35e2b14 copied ListPolyIt from bugfix_overlap_compensation branch (CURA-1966) 2016-08-09 14:18:34 +02:00
Tim Kuipers fadfaa5a80 removed debug code (CURA-1956) 2016-08-09 11:42:17 +02:00
Tim Kuipers fc962709b0 fix: clipper offset bug testing (CURA-1956) 2016-08-09 11:16:48 +02:00
Tim Kuipers a848b8c71d fix: UPDATE CLIPPER (CURA-1956)
this was loooooooong overdue
2016-08-09 11:15:35 +02:00
Tim Kuipers dc05c2749a feat: write max z feedrate when overriden by user value (CURA-1049) 2016-08-08 17:01:48 +02:00
Tim Kuipers cea312a23a rename: zPos ==> current_layer_z (CURA-1049) 2016-08-08 14:52:14 +02:00
Tim Kuipers deee23d1f8 fix: generate support interface correctly also inside a model (CURA-2074) 2016-08-08 13:48:54 +02:00
Tim Kuipers d097cfa78f rename: generateSupportRoofs ==> generateSupportInterface (CURA-2074) 2016-08-08 13:38:45 +02:00
Tim Kuipers 09c1df7ea6 Merge branch 'markwal-mergeinfillchanges' 2016-08-08 09:53:39 +02:00
Mark Walker 7f9e034dbb Propagate rename pressure->flow all the way down 2016-08-04 11:14:56 -07:00
Mark Walker 05b5a0b45c Rename pressure to flow and make it per extruder 2016-08-04 10:46:25 -07:00
Mark Walker ca1a076db3 nozzle_size doesn't change in the loop 2016-08-04 10:31:59 -07:00
Mark Walker 36c2bd81d0 Add setting to control autospeed for mergeinfill
Also:
- use travel speed for travel moves and extrusion speeds for
extrusion moves
- get the nozzle size from settings
2016-08-04 10:31:59 -07:00
Tim Kuipers d44c8eb067 Merge branch 'master' of github.com:Ultimaker/CuraEngine 2016-08-04 12:02:44 +02:00
Tim Kuipers 2b81ce1dd5 fix: don't switch to adhesion extruder for skirt when printing raft (CURA-2013) 2016-08-04 12:02:29 +02:00
Tim Kuipers 73df32881a fix: support bottoms now don't check below zero any more (CURA-1013)
taking the max of unsigned int zero and another has no use!
The other value probably wrapped around to unsigned int max_value already
2016-08-02 12:45:05 +02:00
Tim Kuipers 01357eacc4 Merge branch 'master' into feature_support_bottoms 2016-08-02 12:40:05 +02:00
Ghostkeeper fc7c55768a Don't apply first layer speeds on raft layers
This only applied to travel speeds, since raft print speeds are determined by other settings, support is not on the raft layers, and meshes are not on the raft layers.

Contributes to issue CURA-1507.
2016-08-01 13:41:36 +02:00
Ghostkeeper fea300cfc3 Remove unnecessary static cast from int to int
It's already an int.

Contributes to issue CURA-1507.
2016-08-01 13:30:46 +02:00
Arjen Hiemstra 4f4a5dd1e7 Merge branch 'feature_support_settings_from_support_extruder'
* feature_support_settings_from_support_extruder:
  Remove debug statement
  Set settingInheritBase on every mesh in the meshgroup
  Be more robust against wrong input from Arcus
  Distribute global_inherits_stack across meshgroups
  Register SettingExtruder message type
  Sync from frontend: global_inherits_stack message
  feat: setting retrieval inheritance overrides (CURA-1953)
2016-08-01 13:01:18 +02:00
Ghostkeeper 02fe987035 Remove debug statement
Oops. Sorry.

Contributes to issue CURA-2011.
2016-08-01 12:08:46 +02:00
Ghostkeeper 9e7b6212b0 Set settingInheritBase on every mesh in the meshgroup
Also changed the nesting of the for loops around to make it a bit more efficient.

Contributes to issue CURA-2011.
2016-08-01 11:41:44 +02:00
Ghostkeeper 94a3a6b642 Abort thread after it has completed
Otherwise it stays sleeping for 60s. This produced too many threads on OSX.

Contributes to issue CURA-1828.
2016-08-01 11:10:27 +02:00
Tim Kuipers d7eef238ce cleanup: removed dead code (CURA-1647) 2016-07-31 22:12:01 +02:00
Tim Kuipers 3cbfe3b037 fix: retract after each meshgroup (CURA-1829)
also fixes (CURA-1379)
2016-07-31 19:07:55 +02:00
Ghostkeeper 9b8917e763 Be more robust against wrong input from Arcus
A simple range check against the extruder list.

Contributes to issues CURA-2011 and CURA-1953.
2016-07-29 17:38:00 +02:00
Ghostkeeper a5b7b474a6 Distribute global_inherits_stack across meshgroups
Every meshgroup gets the same global_inherits_stack values.

Contributes to issues CURA-2011 and CURA-1953.
2016-07-29 17:18:47 +02:00
Ghostkeeper 839fc30c91 Register SettingExtruder message type
So that we can read it.

Contributes to issue CURA-2011.
2016-07-29 16:29:15 +02:00
Ghostkeeper b8a6888d94 Sync from frontend: global_inherits_stack message
The front-end added the global_inherits_stack SettingExtruder message. We should add it too to be able to read the message. This is a copy from the same file in Cura's front-end.

Contributes to issue CURA-2011.
2016-07-29 16:25:59 +02:00
Jaime van Kessel 14cb8eeabd Removed anciend debug output
This statement of a time before time slowed down the frontend.
2016-07-29 16:17:06 +02:00
Tim Kuipers f9f79fa0e8 fix: only generate skirt polygons for used extruders (CURA-1647)
also cleaned up generateSkirtBrim a bit
also applied code conventions
inadvertently also causes support not to be removed by unprinted skirt
removed skirts_or_brims which didn't need to be a vector (only last elem was used)
2016-07-28 23:20:34 +02:00
Tim Kuipers 691efb3b6e feat: ExtruderTrain::is_used (CURA-1647) 2016-07-28 22:58:45 +02:00
Tim Kuipers 93be9431b7 fix: brim removed support rather than going around it (CURA-1647) 2016-07-28 21:29:46 +02:00
Ghostkeeper 6c757f3fcf Rename draft_shield_height to draft_shield_layers
This was considered better.

Contributes to issue CURA-1295.
2016-07-28 20:06:35 +02:00
Tim Kuipers ae66df7b0a Merge branch 'master' into feature_first_layer_travel_speed 2016-07-28 16:48:48 +02:00
Tim Kuipers d447d9d711 fix: process brim for each meshgroup again (CURA-1721) 2016-07-28 14:22:57 +02:00
Tim Kuipers b30f1c1a2e secret fix: change gcode type comment back to SKIRT 2016-07-28 14:16:08 +02:00
Tim Kuipers 2ff1c876b3 secret fix: change gcode type comment back to SKIRT 2016-07-28 14:14:02 +02:00
Tim Kuipers 6db1097faa API change: support_roof_... ==> support_interface... (CURA-1013) 2016-07-28 14:05:28 +02:00
Tim Kuipers 86cbe1797b Merge branch 'master' into feature_support_bottoms 2016-07-28 13:53:47 +02:00
Tim Kuipers 65f0ba9673 Merge branch 'master' of github.com:Ultimaker/CuraEngine 2016-07-28 13:52:25 +02:00
Tim Kuipers 7d6df9746e fix: always generate skin when layer number is almost at top (CURA-1837)
dont try to compare with non-existent layer number which is too high
2016-07-28 13:52:18 +02:00
Ghostkeeper 2d2196648f Make draft shield limit work with small models
Problem was that the draft shield height limit was measured in number of layers, but it was compared with the height of the first layer to determine if we should skip adding draft shield layers, and the first layer height was measured in microns.

Contributes to issue CURA-1295.
2016-07-28 13:45:18 +02:00
Ghostkeeper 6992bb6e03 Code style: Indentation and brackets
Contributes to issue CURA-1509.
2016-07-28 11:44:49 +02:00
Tim Kuipers dee2f82d87 Merge pull request #374 from Ultimaker/bugfix_slicer_initializer
Properly initialize member variables of classes in slicer.h
2016-07-28 10:54:15 +02:00
Tim Kuipers bec685e004 fix: initialize slicer members to invalid values 2016-07-28 10:51:19 +02:00
Tim Kuipers d38ccb7691 fix: changed round_divide to work with unsigned ints (CURA-1013)
the math was wrong for negative numbers
2016-07-27 18:31:22 +02:00
Tim Kuipers e5036763fe fix: round support z distance up (CURA-1013) 2016-07-27 18:26:04 +02:00
Ghostkeeper 865f97c5d7 Repair draft shield height limitation part 2
Renamed DraftShieldLimitation to DraftShieldHeightLimitation. Also applied the limit to FffGcodeWriter and made the draft shield function more logical and make it only check for the limit if the draft shield height is limited.

Contributes to issue CURA-1295.
2016-07-27 17:48:53 +02:00
Ghostkeeper 0b4b04f31a Don't generate skirt if draft shield is full
If draft shield limitation is set to full but the height is set to 0, don't generate a skirt.

Contributes to issue CURA-1295.
2016-07-27 17:48:53 +02:00
Ghostkeeper 39fea42b92 Fix draft shield limitation setting
The engine now listens to the draft shield limitation. If it's set to full, we use the full height of the print to limit the draft shield rather than the height limit setting.

Contributes to issue CURA-1295.
2016-07-27 17:48:53 +02:00
Ghostkeeper f810356bdb Add draft shield height limitation enum
This enum will be needed to determine what height we should use for the draft shield.

Contributes to issue CURA-1278.
2016-07-27 17:48:53 +02:00
Ghostkeeper 4c41acd946 Re-enable skirt if draft shield disabled but height is not 0
It used to only look at the height.

Contributes to issue CURA-1295.
2016-07-27 17:48:52 +02:00
Ghostkeeper af135fff49 Take draft shield height of 0 if draft shield is disabled
This fixes the boolean setting again.

Contributes to issue CURA-1295.
2016-07-27 17:48:52 +02:00
Tim Kuipers ed4457a3f4 Merge branch 'master' into feature_support_bottoms 2016-07-27 17:40:11 +02:00
Tim Kuipers 7ea9b14a33 fix: retrieve globalish support settings from support extruder (CURA-2003) 2016-07-27 17:10:07 +02:00
Tim Kuipers 957c56c6b2 feat: setting retrieval inheritance overrides (CURA-1953) 2016-07-27 16:28:11 +02:00
Arjen Hiemstra 0a689a0da8 Properly initialize member variables of classes in slicer.h
I get crashes because SlicerSegment::endVertex is used uninitialized.
2016-07-27 15:36:58 +02:00
Ghostkeeper 39efcf5680 Add more asserts for isOutsideTest
This also tests other cases where the point happens to be on other edge cases for other sides of the triangle.

Contributes to issue CURA-1981.
2016-07-27 15:25:37 +02:00
Ghostkeeper 0bc373e935 Remove whitespace at end of line
As per our code style rules.

Contributes to issue CURA-1981.
2016-07-27 15:19:31 +02:00
Ghostkeeper 0c82c00e15 Improve documentation for generateSkirtBrim
Contributes to issue CURA-1678.
2016-07-27 11:56:56 +02:00
Tim Kuipers 1859de69d4 fix: round support_z_distance to nearest layer_height multiple, rather than always rounding up (CURA-1013)
this caused the number of roof/bottom layers to be incorrect (CURA-647)
2016-07-27 11:37:46 +02:00
Tim Kuipers e2fc79889b fix rename: .._support_skin options back to .._support_roof (CURA-1013)
We shouldn't change the interface so easily. This makes the json as it was a couple of ocmmits ago
2016-07-27 11:22:42 +02:00
Ghostkeeper b31646f10d Improve documentation of completeConfigs
Contributes to issue CURA-1507.
2016-07-27 11:18:39 +02:00
Tim Kuipers 10a8265674 Merge branch 'master' into feature_support_bottoms 2016-07-27 11:15:15 +02:00
Tim Kuipers 1445472530 fix: use round_divide where neccesary (CURA-1013) 2016-07-27 11:11:22 +02:00
Tim Kuipers 37f7e18269 fix: inline function definition in header (CURA-1013)
inline functions must always be defined in the header
2016-07-27 11:10:42 +02:00
Simon Edwards a854dc692d Added a lot more logging which kicks in when the -vv flag is given.
Contributes to CURA-1509 Cura in slicing loop, Arcus Error (8)
2016-07-27 11:00:28 +02:00
Tim Kuipers 9cbecf5782 fix: z_distance_top/bottom was computed in micron rather than in layers (CURA-1013) 2016-07-27 10:56:26 +02:00
Tim Kuipers b5575093d0 replace square function by math::square (CURA-1013) 2016-07-27 10:52:51 +02:00
Tim Kuipers 368747b213 feat: math file (CURA-1013)
for simple mathematical constructs
2016-07-27 10:52:05 +02:00
Tim Kuipers 64d3ee9728 rename: support_skin_.. options back to support_roof_... (CURA-1013)
We shouldn't change the interface so easily. This makes the json as it was a couple of ocmmits ago
2016-07-27 10:17:29 +02:00
Tim Kuipers 0ba0188bcd rename: support roof ==> support skin (CURA-1013)
the areas now include both roofs and skins
2016-07-26 18:44:40 +02:00
Tim Kuipers b8691c776e fix: (un)signed int syntax mistake (CUTA-1013) 2016-07-26 18:31:41 +02:00
Tim Kuipers afde126052 refactor: roofs ==> interface (CURA-1013)
the support interface contains areas which are roof and/or bottom
2016-07-26 18:31:14 +02:00
Tim Kuipers 5c22649d7b feat: support bottoms; bugfix: support roof height (CURA-647, CURA-1013) 2016-07-26 18:24:18 +02:00
Tim Kuipers 1e0f2ec7c1 lil refactor: switched two lines (CURA-1972) 2016-07-26 17:20:52 +02:00
Tim Kuipers c0d59627eb removed debug.h
I didn't really know how to write c++ at the time and it only gave difficult to solve problems up till now

(CURA-1792)
2016-07-26 15:58:25 +02:00
Tim Kuipers 836686b90c Merge branch 'slicer-speedup-clean' of https://github.com/scottlenser/CuraEngine 2016-07-26 12:48:21 +02:00
Tim Kuipers 4d7dd3adce fix: reflection graph improvements 2016-07-26 12:45:07 +02:00
Tim Kuipers 14013e657a removed dead code
code was probably used in the past to send layer data in a premature stage
2016-07-26 12:44:48 +02:00
Tim Kuipers 2a1cb236c8 reflection feat: visualize global-only mode 2016-07-26 11:47:07 +02:00
Tim Kuipers 0d17a056a2 lil reflection script fix 2016-07-26 11:22:34 +02:00
Tim Kuipers 722456ba64 lil fix: try-catch for debug code to find clipper bug 2016-07-26 10:29:35 +02:00
Scott Lenser ce1fe33b2e Slicer: Added better documentation on SlicerLayer::Terminus::Index. 2016-07-25 21:40:42 -04:00
Tim Kuipers df3c77d0ce code conventions for commandSocket (CURA-1272) 2016-07-25 17:43:03 +02:00
Tim Kuipers 39e1c5ffd9 fix: set command socket current location when starting printing a meshgroup (CURA-1272) 2016-07-25 17:34:06 +02:00
Tim Kuipers af31f141d8 Merge branch 'layerview_dev' of https://github.com/Johan3DV/CuraEngine into Johan3DV-layerview_dev 2016-07-25 15:53:33 +02:00
Tim Kuipers 5d7687228c test: isinside (CURA-1981) 2016-07-25 11:41:50 +02:00
Tim Kuipers ffb4cdaacd refactor: split off PolygonTest from PolygonUtilsTest (CURA-1981) 2016-07-25 11:35:29 +02:00
Scott Lenser ce10cdecc7 Moved some reference symbols in Slicer to match convention. 2016-07-22 17:53:03 -04:00
Scott Lenser d7806994be Slicer: renamed StitchGridValPointAccess to StitchGridValLocator. 2016-07-22 17:49:32 -04:00
Scott Lenser 6d5762bc59 Slicer: Fixed bug where polylines stitching wouldn't consider joining at start points. 2016-07-22 17:48:12 -04:00
Scott Lenser f96f189d0a Slicer: Improved case when joining polylines via start points. 2016-07-22 17:34:03 -04:00
Scott Lenser d9605a4a53 Slicer: Moved code out of if/else that was common to both cases. 2016-07-22 17:31:46 -04:00
Scott Lenser 0238d1822c Slicer: Comment and formatting improvements. 2016-07-22 17:30:42 -04:00
Scott Lenser d1f38c2be0 Slicer: Documented newer private functions in SlicerLayer. 2016-07-22 16:45:47 -04:00
Scott Lenser 0df427bc7a Slicer: Moved terminus tracking logic into a class. 2016-07-22 15:42:41 -04:00
Scott Lenser 6328aa7210 Slicer: Moved more of connectOpenPolylinesImpl into private functions. 2016-07-22 14:53:54 -04:00
Scott Lenser 2d761096b8 Spacing changes in slicer. 2016-07-22 14:37:12 -04:00
Scott Lenser 1a8b4c6655 Slicer: split off part of connectPolylinesImpl into new function.
Split off the finding possible stitches part into a new private function.
2016-07-22 14:33:55 -04:00
Scott Lenser cdb451b679 Slicer: Moved Terminus and PossibleStitch classes into SlicerLayer.
This moves them from the SlicerLayer::connectPolylinesImpl() function
to the SlicerLayer class.  This results in the declaration movign to
the header file.
2016-07-22 14:24:33 -04:00
Scott Lenser 7aa157c955 Slicer: Made terminus into a class.
This hides the implementation of a polyline index and a flag as an
unsigned int.  This also makes some of the uses more clear because
of the accessor function names.
2016-07-22 14:18:15 -04:00
Scott Lenser 52f71823f4 Removed trailing whitespace in slicer. 2016-07-22 13:31:46 -04:00
Scott Lenser 7522ca3ddc SparseGrid: changed name of PointAccess to Locator. 2016-07-22 13:27:26 -04:00
Scott Lenser b502a74a28 Slicer: switched storage for segments ending in vertex.
This switches the storage for segments ending in a vertex to a vertex *
instead of copying the connected faces of the vertex into a copy
of the vector.
2016-07-22 13:19:43 -04:00
Scott Lenser 3f131e40b9 Added spaces (especially around binary operators) in SparseGrid. 2016-07-22 13:10:09 -04:00
Scott Lenser 9b1a8fab73 Expanded doxygen function comment for SlicerLayer::connectOpenPolylinesImpl. 2016-07-22 12:44:04 -04:00
Scott Lenser 7e5538b65e Improved variable name in slicer. 2016-07-22 12:35:08 -04:00
Scott Lenser 1f60e35bd2 Slicer: Fixed usage of INVALID_TERMINUS value not going through constant. 2016-07-22 12:30:48 -04:00
Scott Lenser 70b3da26b9 Simplified SparseGrid usage in pathOrderOptimizer.
Now using the getNearbyVals() API call which is what the function
really wanted.
2016-07-22 12:26:42 -04:00
Scott Lenser ecdfbd89ed Merge remote-tracking branch 'origin/master' into slicer-speedup-clean 2016-07-22 12:22:15 -04:00
Ghostkeeper 134e52b15f Rename setting skirt_minimal_length to skirt_brim_minimal_length
Because it concerns not only the skirt, but also the brim.

Contributes to issue CURA-1678.
2016-07-22 17:03:21 +02:00
Ghostkeeper 5722a3e086 Rename setting skirt_line_width to skirt_brim_line_width
Because it concerns not only the skirt, but also the brim.

Contributes to issue CURA-1678.
2016-07-22 16:55:27 +02:00
Ghostkeeper e6adbd2f1d Rename jerk_skirt to jerk_skirt_brim
Because it concerns not only the skirt, but also the brim.

Contributes to issue CURA-1678.
2016-07-22 16:52:24 +02:00
Ghostkeeper 533d00cc3a Rename setting acceleration_skirt to acceleration_skirt_brim
Because it concerns not only the skirt, but also the brim.

Contributes to issue CURA-1678.
2016-07-22 16:47:47 +02:00
Ghostkeeper 586e0031d5 Rename skirt_speed to skirt_brim_speed
Because it concerns not only the skirt, but also the brim.

Contributes to issue CURA-1678.
2016-07-22 16:46:44 +02:00
Ghostkeeper 3ab6beb239 Update documentation
Contributes to issue CURA-1678.
2016-07-22 16:35:17 +02:00
Ghostkeeper 1da383d0d0 Make count unsigned
It can't be negative anyway.

Contributes to issue CURA-1678.
2016-07-22 16:33:52 +02:00
Ghostkeeper 479742cea3 Rename skirt_primary_extruder to skirt_brim_primary_extruder in generateSkirtBrim
Because it concerns not only the skirt, but also the brim.

Contributes to issue CURA-1678.
2016-07-22 16:32:42 +02:00
Ghostkeeper e2c206e8ee Rename skirtNr to skirt_brim_number in generateSkirtBrim
Because it concerns not only the skirt, but also the brim.

Contributes to issue CURA-1678.
2016-07-22 16:30:40 +02:00
Ghostkeeper f58c506c6a Rename skirt_sent to skirt_brim_sent in processPlatformAdhesion
Because it concerns not only the skirt, but also the brim.

Contributes to issue CURA-1678.
2016-07-22 16:27:58 +02:00
Ghostkeeper da2a329db4 Rename skirts to skirts_or_brims in generateSkirtBrim
Because it concerns not only the skirt, but also the brim.

Contributes to issue CURA-1678.
2016-07-22 16:26:25 +02:00
Ghostkeeper ecb7ba8904 Rename skirt_polygons to skirt_brim_polygons in generateSkirtBrim
Because it concerns not only the skirt, but also the brim.

Contributes to issue CURA-1678.
2016-07-22 16:21:33 +02:00
Ghostkeeper a84bb21d10 Rename skirt_polygons to skirt_brim_polygons in generateSkirtBrim
Because it concerns not only the skirt, but also the brim.

Contributes to issue CURA-1678.
2016-07-22 16:20:43 +02:00
Ghostkeeper d41c2c6ac2 Rename primary_extruder_skirt_line_width to primary_extruder_skirt_brim_line_width
Because it concerns not only the skirt, but also the brim.

Contributes to issue CURA-1678.
2016-07-22 16:18:57 +02:00
Ghostkeeper 73f9b09951 Change feature type comment in g-code SKIRT to SKIRTBRIM
Because it is used not only for skirt but also for brim. This essentially means an API break, though Cura doesn't rely on this. Printers should not rely on this as per the g-code spec. The only things that rely on this are the postprocessing scripts, but it should be a trivial change for them.

Contributes to issue CURA-1678.
2016-07-22 16:16:51 +02:00
Ghostkeeper ac0b15eb93 Rename PrintFeature::Skirt to SkirtBrim
Because it concerns not only the skirt, but also the brim.

Contributes to issue CURA-1678.
2016-07-22 15:48:32 +02:00
Ghostkeeper 27ab0658df Rename skirt.cpp/h to SkirtBrim.cpp/h
Because it concerns not only the skirt, but also the brim.

Contributes to issue CURA-1678.
2016-07-22 15:44:36 +02:00
Ghostkeeper 759eb0ab90 Rename generateSkirt to generateSkirtBrim
Because it concerns not only the skirt, but also the brim.

Contributes to issue CURA-1678.
2016-07-22 15:40:35 +02:00
Ghostkeeper 2099302a3b Update skirt/brim documentation
Contributes to issue CURA-1678.
2016-07-22 15:35:50 +02:00
Ghostkeeper 8365cb070d Rename skirt_is_processed to skirt_brim_is_processed
Because it concerns not only the skirt, but also the brim.

Contributes to issue CURA-1678.
2016-07-22 15:32:02 +02:00
Ghostkeeper 4121b3da1e Rename processSkirt to proceesSkirtBrim
Because it concerns not only the skirt, but also the brim.

Contributes to issue CURA-1678.
2016-07-22 15:28:36 +02:00
Ghostkeeper 931df895c6 Rename skirt to skirt_brim in processSkirt
Because it concerns not only the skirt, but also the brim.

Contributes to issue CURA-1678.
2016-07-22 15:25:14 +02:00
Ghostkeeper 5b20d02c11 Rename SliceDataStorage::skirt to skirt_brim
Because it concerns not only the skirt, but also the brim.

Contributes to issue CURA-1678.
2016-07-22 15:18:47 +02:00
Ghostkeeper a702fa711d Rename initializeSkirtConfigs to initializeSkirtBrimConfigs
Because it concerns not only the skirt, but also the brim.

Contributes to issue CURA-1678.
2016-07-22 15:06:30 +02:00
Ghostkeeper eeb741bfb6 Rename SliceDataStorage::skirt_config to skirt_brim_config
Because it concerns not only the skirt, but also the brim.

Contributes to issue CURA-1678.
2016-07-22 15:01:21 +02:00
Ghostkeeper 5942bb3d4c Only generate support roof below mesh
Support roof takes quite a lot of time to print, so only generate it below the actual mesh, not where the support area is X/Y expanded or where multiple pieces of support are joined and such.

Contributes to issue CURA-647.
2016-07-22 14:40:20 +02:00
Ghostkeeper dd3007a61e Load support roof height and layer height from mesh
Don't have to pass it through via parameters.

Contributes to issue CURA-647.
2016-07-22 14:23:37 +02:00
Ghostkeeper 0e0119a3e6 Make parameters const and unsigned
Negative is not possible anyway. And these are not changed.

Contributes to issue CURA-647.
2016-07-22 13:49:43 +02:00
Ghostkeeper ef38ed3688 Rename variables according to code style
We use lowercase with underscores.

Contributes to issue CURA-647.
2016-07-22 13:47:17 +02:00
Ghostkeeper 142464ebeb Round support Z-distance up instead of down
The z-distance is rounded to the next layer. This guarantees that there is at least the specified Z-distance.

Contributes to issue CURA-1283.
2016-07-22 13:31:26 +02:00
Ghostkeeper 1d54240c32 Make retraction config take extruder of current plan
Rather than taking the extruder of the current g-code, which is for an entire layer, take the retraction settings of the current extruder plan. This allows for different retraction settings on the same layer rather than just taking the retraction settings that layer begins with.

Contributes to issue CURA-1972.
2016-07-22 11:52:07 +02:00
Johan K 25384faeed Merge branch 'master' of https://github.com/Ultimaker/CuraEngine into layerview_dev 2016-07-22 10:36:34 +02:00
Johan K 610685e13b Removing layer_nr argument from CommandSocket::send* functions. 2016-07-22 03:08:59 +02:00
Johan K ae59b2b8d8 Clean up the interface functions for sending data to the layer view in GUI.
Functions are now static and internally check in the command socket is instansiated to make the using code cleaner.
The sendLine function has been renamed to sendLineTo and only take the destination point to match how data is used and written to gcode.
CURA-1272
2016-07-22 02:29:42 +02:00
Ghostkeeper fe184f9177 Always make tests select from arrays
In some cases it was selecting characters from a string and passed those as a string. That's wrong!

Contributes to issue CURA-1758.
2016-07-21 18:27:49 +02:00
Ghostkeeper bce51f4807 Add setting types polygon and polygons
It just evaluates the default. It doesn't try to edit these.

Contributes to issue CURA-1758.
2016-07-21 18:27:49 +02:00
Ghostkeeper e371c43395 Don't evaluate default_value as fallback
Just take the value itself without evaluating it. Otherwise enum values accidentally get evaluated as a variable.

Contributes to issue CURA-1758.
2016-07-21 18:27:49 +02:00
Ghostkeeper b3f80cec83 Repair evaluation functions
The names of these properties have changed a bit. Also, we're now getting the normal value first and defaulting back to default_value if there is no inheritance functions.

Contributes to issue CURA-1758.
2016-07-21 18:27:49 +02:00
Ghostkeeper e34f2ffc67 Remove commented code
Contributes to issue CURA-1758.
2016-07-21 18:27:49 +02:00
Ghostkeeper 0f0bd3c32c Remove redundant parentheses
As per the code style.

Contributes to issue CURA-1758.
2016-07-21 18:27:49 +02:00
Tim Kuipers 71beb1cc98 fix: no support for infill meshes (CURA-833) 2016-07-21 15:45:07 +02:00
Tim Kuipers bc56e73e36 Merge branch 'feature_remove_extruder_width' 2016-07-21 15:32:40 +02:00
Ghostkeeper ea364c4cd8 Obtain combined infill line width per layer
If the line width is different per combined layer this would get the correct one, and it is also more robust if there are 0 layers in the vector.

Contributes to issue CURA-736.
2016-07-21 13:54:01 +02:00
Ghostkeeper d581957308 Rename primary_skirt_line_width to primary_extruder_skirt_line_width
This was deemed better by the reviewer.

Contributes to issue CURA-736.
2016-07-21 13:36:25 +02:00
Ghostkeeper 11c611c9e4 Restore support for negative conical support angles
Negative conical support angles are also allowed. Only when the support angle is exactly zero, it is nonsensical to generate conical support.

Contributes to issue CURA-736.
2016-07-21 13:32:23 +02:00
Tim Kuipers 5ab937ba03 indent fix only (CURA-833)
only indentation and a lot of bs diff
2016-07-21 11:27:06 +02:00
Tim Kuipers aa5c9d37fd fix: command line slicing was broken (CURA-833) 2016-07-21 11:26:19 +02:00
Tim Kuipers 9de3edee39 debug fix: better debug output of clipper bug 2016-07-21 11:10:43 +02:00
Ghostkeeper 21fa313feb Move support line width into detect overhang points
It's the only place where it's used. This makes the stack trace slimmer, potentially making the program faster. Also, it moves the dependency on the setting closer to where the setting is used.

Contributes to issue CURA-736.
2016-07-21 09:31:00 +02:00
Ghostkeeper 6fb61a3c79 Make a few settings const
While we're at it...

Contributes to issue CURA-736.
2016-07-21 09:24:57 +02:00
Ghostkeeper bc2efcfc39 Rename extrusionWidth to line_width
This line width is the width of the lines in the wireframe mode.

Contributes to issue CURA-736.
2016-07-21 09:19:59 +02:00
Ghostkeeper cb40a72eda Rename extrusionWidth to line_width
This is the width of all wireframe lines.

Contributes to issue CURA-736.
2016-07-20 17:14:26 +02:00
Ghostkeeper 096e8f7675 Remove old code
This prime tower is long unused. The queue import also seems to be unused, since compiling gives no error and a CTRL+F has no results either.

Contributes to issue CURA-736.
2016-07-20 17:10:17 +02:00
Ghostkeeper 87e02722e7 Rename primary_extrusion_width to primary_skirt_line_width
Sometimes it is the brim line width. But this convention is held elsewhere throughout the code too.

Contributes to issue CURA-736.
2016-07-20 17:07:24 +02:00
Ghostkeeper d15387905b Rename innermost_wall_extrusion_width to innermost_wall_line_width
Neighbouring variables are also renamed, such as extrusionWidth that was actually the wall line width.

Contributes to issue CURA-736.
2016-07-20 16:58:50 +02:00
Ghostkeeper 5280c9df10 Correct skin-wall to skin overlap
The skin-wall now has the line width of the inner walls.

Contributes to issue CURA-736.
2016-07-20 16:28:13 +02:00
Ghostkeeper 021c7ac0bf Use inner wall config to extrude skin border lines
This makes the line width with which we're extruding equal to the line width with which we did the insets for these lines.

Contributes to issue CURA-736.
2016-07-20 16:25:00 +02:00
Ghostkeeper 3825e200a6 Make skin insets use inner wall line width
We deemed that the inner wall line width is more akin to the line width you're seeking for the border line of skins, which attaches slin lines that end on the border with infill. More akin than skin line width anyway.

Contributes to issue CURA-736.
2016-07-20 15:39:22 +02:00
Ghostkeeper 6022e44dee Rename extrusion_width to support_line_width
Also made it const.

Contributes to issue CURA-736.
2016-07-20 15:11:51 +02:00
Ghostkeeper b0054e1b39 Move getting skin line width into skin generator
This makes the stack lighter, because the context switch to the functions doesn't need to copy the value over to the stack. Also removes the reference to old terminology: extrusion_width, and makes the variable const.

Contributes to issue CURA-736.
2016-07-20 15:09:51 +02:00
Ghostkeeper 7a1ee0429e Move getting infill line width into infill functions
This makes the stack lighter, because the context switch to the functions doesn't need to copy the value over to the stack. The local variable can be an order of magnitude faster even though it needs to look-up the value from the mesh one additional time. Also removes the reference to old terminology: extrusion_width, and makes the variable const.

Contributes to issue CURA-736.
2016-07-20 15:03:05 +02:00
Johan K fddaa58d67 Merge branch 'master' of https://github.com/Ultimaker/CuraEngine into layerview_dev 2016-07-20 14:49:24 +02:00
Ghostkeeper 0ff87b785f Split speed_layer_0 into two settings
There are now distinct settings for speed_print_layer_0 (the extrusion moves) and speed_travel_layer_0 (the non-extrusion moves).

Contributes to issue CURA-1507.
2016-07-20 10:54:55 +02:00
Ghostkeeper 71df0e2586 Initial layer travel speed uses initial layer config
It uses the same gradient as the rest of the speeds. This is per extruder though.

Contributes to issue CURA-1507.
2016-07-19 14:49:00 +02:00
Ghostkeeper 53c8cc5e78 Document initialLayersSetup()
Better structured, really.

Contributes to issue CURA-1507.
2016-07-19 14:41:00 +02:00
Tim Kuipers aa87a720c0 refactor: code conventions (CURA-1856) 2016-07-19 13:42:25 +02:00
Tim Kuipers 6e171f795c Merge branch 'scottlenser-add-convex-hull' 2016-07-19 13:32:22 +02:00
Tim Kuipers e76cda3ea8 Merge branch 'add-convex-hull' of https://github.com/scottlenser/CuraEngine into scottlenser-add-convex-hull 2016-07-19 13:23:58 +02:00
Ghostkeeper 8794688c48 Merge branch 'feature_tetrahedral_infill' 2016-07-19 09:28:25 +02:00
Tim Kuipers 957c82715d fix: use print_layer_count everywhere after infill meshes have been generated/confined (CURA-833) 2016-07-18 18:06:37 +02:00
Tim Kuipers c0813b2c77 fix: send layer info after processing infill meshes (CURA-833) 2016-07-18 18:04:28 +02:00
Tim Kuipers 3042483f73 update mesh.layer_nr_max_filled_layer during processing infill meshes (CURA-833) 2016-07-18 18:00:52 +02:00
Tim Kuipers 3abc718240 fix: reserve enough layers in the vector (speedup) (CURA-833) 2016-07-18 18:00:09 +02:00
Tim Kuipers a52208b15e refactor: rename layer_count ==> slice_layer_count because infill meshes may be sliced at layers which aren't printed (CURA-833) 2016-07-18 17:58:53 +02:00
Ghostkeeper edd44de9e3 Spelling fixes
Contributes to issue CURA-1925.
2016-07-18 17:17:59 +02:00
Tim Kuipers d4b1c70790 fix: limit infill meshes to the own infill area of other meshes rather than their basic infill area (CURA-833)
second order infill mehses could overlap with first order infill meshes before
2016-07-18 15:54:40 +02:00
Tim Kuipers 534e265fd2 refactor: factored out a new function getOwnInfillArea whic returns the infill_area_own or the infill_area (CURA-833) 2016-07-18 15:53:27 +02:00
Tim Kuipers 120de96bb5 fix: optional assignment used wrong constructor (CURA-833) 2016-07-18 14:47:13 +02:00
Tim Kuipers a611739ff7 Merge branch 'master' into feature_gradual_infill 2016-07-18 12:20:16 +02:00
Tim Kuipers 791e436222 fix: only first infill mesh part got removed from infill of normal mesh (for gradual infill branch) (CURA-833) 2016-07-18 12:17:10 +02:00
Tim Kuipers d16f52e776 fix: only first infill mehs part got removed from infill of normal mesh (CURA-833) 2016-07-18 12:14:45 +02:00
Tim Kuipers a99020e995 Merge branch 'master' into feature_gradual_infill 2016-07-18 11:57:50 +02:00
Tim Kuipers 5237b1bb01 fix: made raft top layers into zigzag (CURA-1637)
previous commit was actually for the middle layers instead of the top layers
2016-07-15 15:34:25 +02:00
Tim Kuipers 7e0d44cfcb fix: combing thought it was never inside when printing the raft (CURA-1637) 2016-07-15 15:31:11 +02:00
Tim Kuipers 453b3ebbc5 fix: made raft top layers into zigzag (CURA-1637) 2016-07-15 15:10:07 +02:00
Tim Kuipers 473b925814 feat/fix: changed mat GUID to string and retrieve it from settings (CURA-1836) 2016-07-15 14:27:57 +02:00
Tim Kuipers 4199fcf8ac feat/fix: changed mat GUID to string and retrieve it from settings (CURA-1836) 2016-07-15 14:27:24 +02:00
Tim Kuipers 203f04571c fix: delete instance when de-assigning an optional value (CURA-836) 2016-07-15 13:45:45 +02:00
Tim Kuipers 186472c26e feat: tetrahedral infill (CURA-1925) 2016-07-15 12:35:48 +02:00
Tim Kuipers dc2b505274 fix: combination of gradual infill and infill mehses didn't work (CURA-836)
The part.infill_area should remain the whole initial infill area for combing
During the generation of the part.infill_area_per_combine_per_density it refered to part.infill_area, rather than the infill-mesh-limited infill
I had to introduce an intermediate result - part.infill_area_own - which records the area where that mesh should print its infill pattern
In case there are no infill meshes the part.infill_area_own remains a nullptr, so that we don't waste resources.
After it's used and incorporated into infill_area_per_combine_per_density, its destroyed.
2016-07-14 17:57:16 +02:00
Tim Kuipers 9adc0a128c fix: optional::operator=(nullptr) didn't work (CURA-836) 2016-07-14 17:51:12 +02:00
Tim Kuipers e6a5eccf03 Merge branch 'master' into feature_gradual_infill 2016-07-14 16:29:28 +02:00
Johan K 71ea91b61b Implement adding extruder number to path compiler 2016-07-14 12:13:14 +02:00
Tim Kuipers 00d6a55836 lil: less whitespace at end of lines 2016-07-14 12:12:25 +02:00
Tim Kuipers 4308c74451 fix: multiVolumesOverlap failed when two meshes are directly adjacent in the X direction (CURA-833)
when there was no X which covered both models
2016-07-14 12:05:17 +02:00
Tim Kuipers 757df8c7c8 fix: let combing not see infill meshes (CURA-833) 2016-07-14 11:39:38 +02:00
Tim Kuipers ff5cc9399d refactor: lil rename (CURA-833) 2016-07-14 11:35:46 +02:00
Johan K ddf7bbe06e Changed the data type of the layer visualization data from int64 to float.
Also added extruder number and point dimensionality to the message.
2016-07-14 11:00:39 +02:00
Tim Kuipers e34608442a doc: processInfillMesh (CURA-833) 2016-07-14 10:50:37 +02:00
Tim Kuipers c0446f81e0 Merge branch 'master' of github.com:Ultimaker/CuraEngine 2016-07-13 17:30:13 +02:00
Ghostkeeper 27ac98caa5 Code style: Whitespace around binary operators
Contributes to issue CURA-833.
2016-07-13 15:47:37 +02:00
Ghostkeeper ebcfad8200 Codestyle: Whitespace around binary operators
Contributes to issue CURA-833.
2016-07-13 15:45:52 +02:00
Ghostkeeper 69665a0d4a Codestyle: Space after comma and no whitespace at end of line
Contributes to issue CURA-833.
2016-07-13 15:13:21 +02:00
Johan K a50d6fe5a9 Merge branch 'master' of https://github.com/Ultimaker/CuraEngine into layerview_dev 2016-07-13 14:52:11 +02:00
Ghostkeeper bed556a5e6 Codestyle: Brackets after if-statements
Instead of making new brackets after every if-statement, I opted for making it into or-clauses.

Contributes to issue CURA-833.
2016-07-13 14:48:53 +02:00
Tim Kuipers a86c5b1105 doc: documented ExtruderPlan 2016-07-13 14:34:05 +02:00
Tim Kuipers 3db1c2580f Merge branch 'feature_gradual_infill' of github.com:Ultimaker/CuraEngine into feature_gradual_infill 2016-07-13 14:19:22 +02:00
Tim Kuipers 2925af497c lil doc 2016-07-13 14:17:07 +02:00
Johan K 0bd5ae9e01 Added documentaion
More documentation for PathCompiler and SliceDataStruct.
2016-07-13 14:03:46 +02:00
Tim Kuipers eff7f0e326 fix: always retract after priming (CURA-1816) 2016-07-13 11:09:12 +02:00
Scott Lenser a6ad786443 Cleaned up size handling in convexHull. 2016-07-12 10:08:35 -04:00
Scott Lenser ce85280971 Merge remote-tracking branch 'origin/master' into slicer-speedup-clean 2016-07-12 09:13:41 -04:00
Tim Kuipers a7bc153db5 Merge branch 'feature_overhang_dropdown' 2016-07-12 11:25:20 +02:00
Tim Kuipers 3d98bb7e74 Merge branch 'feature_firmware_travel_settings' 2016-07-12 11:06:56 +02:00
Tim Kuipers cc632cd201 Merge branch 'master' of github.com:Ultimaker/CuraEngine into feature_fan_control_per_extruder 2016-07-12 11:02:31 +02:00
Tim Kuipers b0ee1ca57d Merge branch 'scottlenser-slenser-cleanup-pr-A' 2016-07-12 10:35:10 +02:00
Tim Kuipers e7992fc17a fix: USE_CPU_TIME iff in debug mode (CURA-1856) 2016-07-12 10:28:02 +02:00
Tim Kuipers 3f2162d76c doc: better documentation and function naming (CURA-1856) 2016-07-12 10:23:48 +02:00
Johan K 019116cd33 Merge branch 'master' of https://github.com/Ultimaker/CuraEngine into layerview_dev 2016-07-12 01:03:19 +02:00
Johan K b0f725c1e5 Added extruder nr to PathSegment definition in Cura.proto 2016-07-12 01:02:24 +02:00
Tim Kuipers 17c125d395 fixed header guard of WallsComputation 2016-07-11 22:29:17 +02:00
Tim Kuipers d0d0532cb8 Merge branch 'slenser-cleanup-pr-A' of https://github.com/scottlenser/CuraEngine into scottlenser-slenser-cleanup-pr-A 2016-07-11 18:35:31 +02:00
Tim Kuipers 563be4980d doc: visual explanation of gradual infill shift and line dist (CURA-836) 2016-07-11 18:10:29 +02:00
Tim Kuipers 4a91663bb4 fix: gradual infill steps are skipped through regularly now (CURA-836)
whenb computing gradual infill, we skip layersto compute which regions count as top. These skips are now such that
you end exactly one gradual infill step above.
2016-07-11 17:44:30 +02:00
Tim Kuipers f486d6be6f bugfix: sqrt doesn't return a constexpr (CURA-833) 2016-07-11 16:34:21 +02:00
Tim Kuipers 945711f10a bugfix: sqrt doesn't return a constexpr (CURA-833) 2016-07-11 16:27:36 +02:00
Tim Kuipers 0ae670ce0c Merge branch 'master' of github.com:Ultimaker/CuraEngine 2016-07-11 16:16:07 +02:00
Tim Kuipers 2db4730f00 lil: removed done TODO CURA-833 2016-07-11 16:04:25 +02:00
Jaime van Kessel 09b36ecdd8 Merge branch 'feature_cubic_isometric_infill' of github.com:Ultimaker/CuraEngine 2016-07-11 14:41:08 +02:00
Tim Kuipers 5e83d4252d fix: handle inactive temp of second nozzle on first layer (CURA-1508) 2016-07-11 13:37:08 +02:00
Tim Kuipers a69270e212 fix/refactor: factored writePrimeTrain out of startExtruder so that we can enforce printing temperature before priming (CURA-1508) 2016-07-11 13:14:48 +02:00
Ghostkeeper d197c7f3d7 Fix spelling in documentation
Contributes to issue CURA-836 and a few others probably.
2016-07-11 10:26:35 +02:00
Tim Kuipers c82a8c5a47 fix: warning msg bug: was string instead of Cstring (CURA-1568) 2016-07-11 10:22:42 +02:00
Scott Lenser 288f053abd Updated mentions of BucketGrid in comments to SparseGrid.
Some of the comments had mentions of BucketGrid were the code had
already been updated to change BucketGrid2D uses to SparseGrid.
I didn't notice them before because of the different spelling.
2016-07-09 12:48:13 -04:00
Scott Lenser f73586190e Fixed warning message about unused variable. 2016-07-08 19:53:03 -04:00
Scott Lenser 0fd0dd6869 Removed BucketGrid2D which has been replaced by SparseGrid. 2016-07-08 19:24:14 -04:00
Scott Lenser dee0ae12d6 Converted polygonUtils to SparseGrid from BucketGrid2D.
This also converts Comb which relies on polygonUtils (Comb just stores
the type from polygonUtils).
2016-07-08 19:21:44 -04:00
Scott Lenser c2571d41af Converted pathOrderOptimizer to SparseGrid from BucketGrid2D. 2016-07-08 18:39:45 -04:00
Scott Lenser c8fd58376b Converted BucketGrid2D test to SparseGrid test. 2016-07-08 17:53:44 -04:00
Scott Lenser bce0a8a3a8 Added parameters to SparseGrid constructor to allow more control of map.
This adds functionality that was present in BucketGrid2D's constructors.
2016-07-08 16:59:26 -04:00
Scott Lenser 25c2f7086d Moved SparseGrid::processNearby into public interface. 2016-07-08 16:44:49 -04:00
Scott Lenser 941f4e3a66 Added getNearest() function to SparseGrid.
Refactored so that getNearest and getNearby can share a lot of the
implementation.
2016-07-08 16:42:15 -04:00
Scott Lenser 6d8d453df9 Added missing doxygen comment for SparseGrid. 2016-07-08 15:35:33 -04:00
Scott Lenser 90c212b52e Split SparseGrid into an invasive and non-invasive version.
The invansive version requires that the stored type being able to
provide a Point location on demand.  This is a general version in
case the type being stored already has a location in it.  The
non-invasive version is more convenient if the type to be stored
does not already contain a Point location.
2016-07-08 15:32:32 -04:00
Scott Lenser db79eb7ece Added convexHull function for Polygons.
This renames the previous version which is an approximate convex hull
to approxConvexHull.
2016-07-08 13:29:50 -04:00
Scott Lenser 9afcbddf29 Added rounding to coordinates from slicing of mesh. 2016-07-08 13:26:21 -04:00
Scott Lenser c4c221145e More const correctness. 2016-07-08 13:24:56 -04:00
Scott Lenser 1956fc00d3 Added error message if inherited JSON file can't be found. 2016-07-08 13:16:56 -04:00
Scott Lenser 8ac6c3b597 Changed signature of Mesh::getFaceIdxWithPoints to avoid redundant calculation. 2016-07-08 13:16:00 -04:00
Scott Lenser 76b3c8757d Fixed bug which sent multiple finished slice messages.
The slicing finished message is already sent in CommandSocket::connect().
This confused the GUI since it is only expecting 1 finished slice message.
2016-07-08 13:11:52 -04:00
Scott Lenser c6b6688170 Added code to use cpu time instead of wall clock time for timings.
This is controlled by a #define on which timings to use.
2016-07-08 13:10:18 -04:00
Scott Lenser d2c80127ef Fixed bug in print out about number of layers. 2016-07-08 13:09:19 -04:00
Scott Lenser 3ada6f266c Switched command_line_settings to version 2 from version 1. 2016-07-08 13:03:08 -04:00
Scott Lenser 4b5553019e Fixed bug in bridge generation.
It was calculating the angle to use for infill but then not using it.
This makes it use the calculated angle.  This makes the bridge
generation go from basically completely non-functional to just mostly
non-functional.
2016-07-08 12:59:41 -04:00
Scott Lenser 4fd499f7a1 Correctness improvements to SlicerLayer::makeBasicPolygonLoop.
From the slicing, we know which edge generated the end point of the
segment.  We then know that the face that shares this edge is the only
candidate to have generated the next segment.  This avoids checking
the other 2 segments.

Improved logic used in SlicerLayer::getNextSegmentIdx().  The previous
version only considered candidate faces for extending the current
polygon loop by looking at faces that shared an edge.  This works for
many models, but if the slice height exactly intersects vertices of
the mesh, then the segment that would extend the loop is not typically
found.  We know whether we hit a vertex with the slice from the
slicing calculation.  There is a slight cost to checking for equality
to see if we hit a vertex.  This can very slightly slow down normal
models but substantially increase speed on bad case models.  This
extends the logic to use the faces connected to the vertex that the
segment ended on to try to extend the polygon loop.  Theoretically,
this adds a slight performance penalty to makeBasicPolygonLoops when
vertices were hit by the slice.  However, in very limited testing,
this extra time is not measurable.  Adding this improved correctness
makes a big difference in the number of polygon loops successfully
constructed.  In a bad case model, the number of polygons found
increased from 0 to 19 and the number of open polylines for the next
stage of processing went from 6357 to 0.  This made the
connectOpenPolylines() go from taking .048 seconds to 0.  The overall
effect on this model was to reduce the slicing time from 0.084 to 0.04
seconds (this is a small model for testing so total times are low).
2016-07-08 12:50:03 -04:00
Scott Lenser 28aedf57c5 Sped up SlicerLayer::connectOpenPolylines and SlicerLayer::stitch.
Added use of spatial data structure in SlicerLayer::stitch().  Added
SparseGrid spatial data structure.  This is similar to BucketGrid2D
but a bit more general and without the possibility of duplication in
returned points.  SparseGrid does not offer a findNearestObject
function like BucketGrid2D does, although one could be added if
desired.

Sped up SlicerLayer::stit() further by only finding nearby points
once.  The possible stitch points are calculated once and remembered.
They are put into a priority queue.  A bidirectional map (via vectors)
is used to keep track of the transforms that happen to the polygons to
map from the original polyline ends to the new polyline ends.

Combined stitch and connectOpenPolylines implementations.
connectOpenPolylines basically does the same thing as stitch except
has a smaller search radius and doesn't allow for inverting edges.  I
expressed these as parameters to the stitch implementation and then
reused the implementation.  It is now much faster.
connectOpenPolylines has gone from O(n^2) to O(n) and stitch has gone
from O(n^3) to O(n).  connectOpenPolylines has also gotten more
correct.  With the original version,if polys 0 -> 10 -> 5 formed a
chain, then 0 -> 10 would be merged into 0 but the 10 -> 5 would never
be used.  0 -> 10 would be merged into 0, but this new 0 would not be
considered for merging with 5 since 10 > 5.  It also wouldn't be
considered for merging 10 with 5 because 10 has already been cleared
out.
2016-07-08 12:34:47 -04:00
Scott Lenser 28e6a54961 Added timer for time to load mesh. 2016-07-08 12:06:06 -04:00
Scott Lenser b1b49f16e0 Added timers in slicer.
This gives the breakdown between intersecting planes with the model
and the conversion of the resulting segments into polygons.
2016-07-08 12:02:17 -04:00
Scott Lenser 6b72d52c65 Added new spatial data structure SparseGrid.
This class is intended to be used for speeding up fixed radius
nearby neighbor searches.
2016-07-08 11:48:41 -04:00
Scott Lenser 07d416691a Add move version of adding Polygon to Polygons. 2016-07-08 11:43:15 -04:00
Scott Lenser 960c56a9fa Added a convenience typedef for the type of a coordinate in a Point. 2016-07-08 11:33:44 -04:00
Scott Lenser a18b05f347 Fix to make bridging work much better. 2016-07-08 14:22:45 +02:00
Tim Kuipers 4d46fbea8f fix: conical overhang wouldn't do anything for an angle of zero (CURA-1412)
It should then drop any overhang down: \ becomes L
2016-07-08 00:00:48 +02:00
Tim Kuipers 5620abfd95 fix: make infill mesh AABB collision detection take into account horizontal expansion (CURA-833) 2016-07-07 22:17:41 +02:00
Tim Kuipers 3d307112de fix: infill meshes couldn't handle zero infill meshes (CURA-833)
zero infill meshes didn't generate any infill areas, while infill mehses assumed there to be infill areas_per_combine
2016-07-07 22:07:39 +02:00
Tim Kuipers 2c5639097e fix: got a warning about an uninitializes unused variable 2016-07-07 20:47:44 +02:00
Tim Kuipers cbf5d962b7 fix: catch temp flow graph reading input errors (CURA-1792) 2016-07-07 20:42:18 +02:00
Tim Kuipers 744264481a ignore callgrind files 2016-07-07 20:09:52 +02:00
Tim Kuipers 2cd22bdfd5 Merge branch 'master' into feature_fan_control_per_extruder 2016-07-07 17:33:35 +02:00
Tim Kuipers c259d90def fix: extruder switched to old extruder instead of new one (CURA-1816 and CURA-1508) 2016-07-07 17:33:21 +02:00
Tim Kuipers a7b3d53872 Merge branch 'master' into feature_fan_control_per_extruder 2016-07-07 16:50:21 +02:00
Tim Kuipers 57219beb98 fix: nozzle switch was never written (CURA-1508 CURA-1816) 2016-07-07 16:49:31 +02:00
Tim Kuipers 8f0c3c9a49 Merge branch 'feature_fan_control_per_extruder' of github.com:Ultimaker/CuraEngine into feature_fan_control_per_extruder 2016-07-07 16:47:57 +02:00
Tim Kuipers 6adfdd7ad4 Merge branch 'master' into feature_fan_control_per_extruder 2016-07-07 16:42:44 +02:00
Tim Kuipers 59b516702e Merge branch 'master' of github.com:Ultimaker/CuraEngine 2016-07-07 15:19:08 +02:00
Tim Kuipers 78c155b1ab fix: only perform prime gcode for griffin (CURA-1816 CURA-1508) 2016-07-07 15:18:25 +02:00
Tim Kuipers f39a3e62e7 fix: only prime the initial extruder at the start of a print (CURA-1508) 2016-07-07 15:14:24 +02:00
Tim Kuipers 00bcbe7192 fix: get prime location from settings and use travel speed to get there when switching to a yet unused extruder (CURA-1816 and CURA-1508) 2016-07-07 15:13:37 +02:00
Tim Kuipers ab850577b5 fix: initial planned extruder was always set to zero (CURA-1816) 2016-07-07 15:10:45 +02:00
Tim Kuipers 307551b1db fix: skirt assumed extruder 0 for primary adhesion extruder rather than adhesion_extruder_nr (CURA-1816) 2016-07-07 13:33:25 +02:00
Tim Kuipers 9a09cdc18a feat/refactor: factored out startExtruder from GCodeExport::switchExtruder (CURA-1816) 2016-07-07 13:25:28 +02:00
Tim Kuipers dfcc993034 refactor: replaced old SliceDataStorage::getExtrudersUsed(.) with GcodeExport::getExtruderIsUsed (CURA-1816) 2016-07-07 13:24:10 +02:00
Ghostkeeper 65df6439fa Codestyle: Spaces around operators
Contributes to issue CURA-1792.
2016-07-07 11:43:22 +02:00
Jaime van Kessel 43a51f5757 Changed extruder_nr to int (instead of uint)
CURA-1687
2016-07-06 15:31:38 +02:00
Tim Kuipers 96a2ac56c5 fix: don't give warnings for known parent settings (secretly on CURA-1792)
the frontend sends all known settings (and categories) via the command socket even though it should know which settings will be used by the engine.
This is because the json file is the interface ofthe engine and so the frontend sends everything in the interface.
2016-07-06 15:15:26 +02:00
Ghostkeeper 63cd06ca02 Fix typo
Contributes to issue CURA-1568.
2016-07-06 14:59:00 +02:00
Tim Kuipers 39da22630f bugfix: PolygonUtils::findClose(... BucketGrid2D) return pointer to heap resulting in mem leaks (CURA-1792)
now solved with optional
2016-07-06 14:47:19 +02:00
Ghostkeeper 3528b9eca7 Remove TODO
We don't need to do this. Discussed with Tim and Paul.

Contributes to issue CURA-1568.
2016-07-06 14:42:33 +02:00
Tim Kuipers 8d7827aa87 fix: parsing of temp flow graph was buggy ==> rewrite (CURA-1792) 2016-07-06 14:35:38 +02:00
Tim Kuipers c73084bbd1 fix: instantiate command socket after loading the json file (CURA-1792)| 2016-07-06 14:31:24 +02:00
Tim Kuipers bf372cb3aa fix: merge conflic resolution for fan speeds per extruder (CURA-1568)
The ExtruderPlan needed access to the retraction_config for that extruder
2016-07-05 17:44:04 +02:00
Tim Kuipers 0b8c30616a Merge branch 'master' into feature_overhang_dropdown 2016-07-05 15:22:22 +02:00
Tim Kuipers a7720bcfbf Merge branch 'master' of github.com:Ultimaker/CuraEngine 2016-07-04 17:20:14 +02:00
Tim Kuipers bf19300def fix: raft outline now uses rounded offset (CURA-1835) 2016-07-04 17:19:59 +02:00
Jaime van Kessel 9a34e09806 Only send material estimates for extruders a machine has.
CURA-1687
2016-07-04 16:51:43 +02:00
Jaime van Kessel 62a90f86c6 Merge branch 'master' of github.com:Ultimaker/CuraEngine into SendMaterialEstimatesOfBothExtrudersToFrontend 2016-07-04 16:17:47 +02:00
Tim Kuipers f3b6042243 fix: fixing output stream precision when outputting to standard out 2016-07-04 13:54:48 +02:00
Tim Kuipers 795d68d142 fix runtest.py: new setting attributes after settings rework (CURA-1828) 2016-07-04 12:26:10 +02:00
Tim Kuipers c8e9091764 Merge branch 'feature_retraction_settings_per_extruder' 2016-07-04 12:02:26 +02:00
Tim Kuipers 4b43c96cbc Merge branch 'feature_zhop_over_other_material' 2016-07-04 11:59:55 +02:00
Tim Kuipers 4ba0ae104e Merge branch 'master' of github.com:Ultimaker/CuraEngine 2016-07-04 11:55:55 +02:00
Tim Kuipers f99c8b86cc fix runtest.py: new setting attributes after settings rework (CURA-1828) 2016-07-04 11:55:32 +02:00
Tim Kuipers 5c7862287f fix runtest.py: setting category structure after settings rework (CURA-1828) 2016-07-04 11:55:02 +02:00
Tim Kuipers a2c8311c68 fix/feat: gradual infill: pass settings through from frontend and choose better hardcoded values (CURA-836) 2016-07-01 22:27:25 +02:00
Tim Kuipers 018f952a67 fix: linear based infill scaline algorithm was broken (CURA-836) 2016-07-01 21:39:01 +02:00
Tim Kuipers b05928fb52 bugfix: infill shifting could result in sigaborts (CURA-836, CURA-1723) 2016-07-01 21:38:53 +02:00
Tim Kuipers 8b5f2f8ff8 fix/feat: gradual infill now also working for infil thickness aka infill combine (CURA-836) 2016-07-01 21:36:40 +02:00
Tim Kuipers 50d92ff91e fix: linear based infill scaline algorithm was broken (CURA-836) 2016-07-01 17:41:01 +02:00
Jaime van Kessel e3c0439575 Merge branch 'master' of github.com:Ultimaker/CuraEngine 2016-07-01 17:22:48 +02:00
Jaime van Kessel a0f624992d Merge branch 'feature_time_estimates_per_layer' of github.com:Ultimaker/CuraEngine 2016-07-01 17:09:42 +02:00
Tim Kuipers a41a0285f0 lil: removed unused var (CURA-836) 2016-07-01 16:51:55 +02:00
Tim Kuipers dbeab1ec05 fix: gradual infill logic was the wrong way around (CURA-836) 2016-07-01 16:51:25 +02:00
Tim Kuipers b81b956965 bugfix: infill shifting could result in sigaborts (CURA-836, CURA-1723) 2016-07-01 14:54:06 +02:00
Tim Kuipers db2462882c feat: Infill no accepts extra parameter for etra_infill_shift (CURA-836) 2016-07-01 14:09:34 +02:00
Tim Kuipers cc0f0918d3 feat/fix: generate infill lines for gradual infill (CURA-836) 2016-07-01 13:59:43 +02:00
Tim Kuipers 3d93407b61 feat/fix: SkinInfillAreaComputation::generateGradualInfill (CURA-836) 2016-07-01 13:37:02 +02:00
Tim Kuipers ead062757a refactor: part.infill_area_per_combine ==> part.infill_area_per_combine_per_density (CURA-836)
from vector of polygons to vector of vectors of polygons
2016-07-01 11:47:17 +02:00
Tim Kuipers 35b1a42cf3 fix: moved cubic shift computation into a static double (CURA-1723) 2016-07-01 01:37:04 +02:00
Tim Kuipers 420508099a feat: cubic isometric infill computation (CURA-1723) 2016-07-01 00:36:43 +02:00
Tim Kuipers 7d1586ec4c refactor: pass down z height into Infill computation (CURA-1723) 2016-07-01 00:33:09 +02:00
Tim Kuipers cc40088b3e feat: shift linear based infill types (CURA-1723) 2016-06-30 23:47:11 +02:00
Tim Kuipers e28f64d36d fix: removed unused safe_outline_offset (remove overlapping wall parts) (CURA-1723) 2016-06-30 23:10:51 +02:00
Tim Kuipers 0357102399 feat: dont heat up unused extruder (CURA-1508) 2016-06-30 18:01:10 +02:00
Tim Kuipers bdd1a5c4ed bugfix: bs init of extruder_attr.is_used (CURA-1508) 2016-06-30 17:38:44 +02:00
Tim Kuipers d9b47a8c96 refactor: lil rename n ==> extruder_nr (CURA-1508) 2016-06-30 17:27:45 +02:00
Tim Kuipers 507aa1c9d9 fix: initialize gcodeExport::extr_attr::is_used (CURA-1508) 2016-06-30 17:26:44 +02:00
Tim Kuipers c2a0dd952c feat: gcodeExport::extr_attr::is_used (CURA-1508) 2016-06-30 17:26:24 +02:00
Tim Kuipers edc4e3e57b refactor: introduce cpp file for ExtruderTrain (CURA-1508) 2016-06-30 17:07:52 +02:00
Tim Kuipers cbf7960e08 lil codestyle fix 2016-06-30 10:55:36 +02:00
Javier Lechuga 74e52455fa SendMaterialEstimatesOfBothExtrudersToFrontend. Including sendPrintTimeMaterialEstimates in protobuf scheme. CURA-1687 2016-06-30 09:49:46 +02:00
Javier Lechuga fc7a60b34a SendMaterialEstimatesOfBothExtrudersToFrontend. First commit not ready yet. CURA-1687 2016-06-30 09:49:45 +02:00
Tim Kuipers 6fa82e044b fix: skin areas were always wrong (CURA-1773) 2016-06-29 17:59:05 +02:00
Tim Kuipers 8dbfb70c67 fix: retrieve machine_min_cool_heat_time_window per extruder (CURA-1783) 2016-06-29 14:58:37 +02:00
Tim Kuipers 513d1347ca feat: retrieve minimal cooling+heating time window from settings (CURA-1783) 2016-06-29 14:44:43 +02:00
Tim Kuipers 97d895b0a3 feat: don't allow unused extruder to cool down when time window is too small (CURA-1783) 2016-06-29 14:34:41 +02:00
Ghostkeeper ac1087dda3 Merge branch 'materials_test'
Conflicts:
	src/gcodePlanner.cpp
2016-06-29 14:26:15 +02:00
Tim Kuipers f23a91f0aa refactor: rename time_to_start_warmup_earlier_to_be_extra_sure_we_dont_have_to_wait ==> extra_preheat_time (CURA-1731) 2016-06-29 12:50:28 +02:00
Tim Kuipers dd7fb1941f fix: time within path where preheat commands were inserted was inverted (CURA-1731) 2016-06-29 10:22:32 +02:00
Tim Kuipers 54f7a45f65 small codestyle fixes (CURA-1506) 2016-06-28 18:48:22 +02:00
Tim Kuipers 7d7ca8ae4a refactor: inversed logic of and calls to LayerPlanBuffer::insertPreheatCommand (CURA-1731) 2016-06-28 18:41:50 +02:00
Tim Kuipers 9ab0839b4a indent only (CURA-1731) 2016-06-28 18:33:24 +02:00
Tim Kuipers 844bfd34ab refactor+bugfix: simplified LayerPlanBuffer by passing around a vector of extruder plans rather than layers AND fixed a bug in handleStandbyTemp (CURA-1731)
handleStandbyTemp set the standby temp of the wrong extruder plan...
2016-06-28 18:32:59 +02:00
Tim Kuipers 7a87848562 refactor: layer plan buffer: bubble up special case for very first extruder plan of a meshgroup (CURA-1731) 2016-06-28 18:28:28 +02:00
Tim Kuipers 69a62a74ca fix: removed superfluous if case (CURA-1731) 2016-06-28 17:59:30 +02:00
Tim Kuipers 162f39e3fb fix: the standby temperatures were reset for all previous extruder plans with the same extruder in the buffer (CURA-1731) 2016-06-28 17:45:29 +02:00
Tim Kuipers 7fa436de51 fix: adjust lowest temperature when there's no time to heat to the required temperature (CURA-1731) 2016-06-28 17:44:55 +02:00
Tim Kuipers 1ef7ae46b2 lil: includes fixed for optional (CURA-1731) 2016-06-28 16:40:55 +02:00
Tim Kuipers 8b9695b913 doc: optional documentation (CURA-1731) 2016-06-28 16:39:34 +02:00
Tim Kuipers 5879a3cdaa fix: set extruder temps at ExtruderPlan start fixed instead of via TempInsert (CURA-1731) 2016-06-28 16:33:54 +02:00
Tim Kuipers 2236b3afeb feat: crude implementation of c++17::std::optional (CURA-1731) 2016-06-28 16:14:35 +02:00
Tim Kuipers ed283a978b feat: let Preheat compute from_temperature along with heating_time and bubble the result up (CURA-1731) 2016-06-28 14:03:48 +02:00
Tim Kuipers 9f44d8362a fix: start cooldown in new extruder plan instead of old to combat snowballing effect (CURA-1731)
snowballing: when we start cooling T0 before we require the temp of T1 to be reached, due to small discrepancy between the computed and actual heatup times, the time it takes to actually reach the required temp of T1 - while computed to be zero - causes T0 to drop in temperature in that time. This in turn will mean it will also take longer to heat up again, creating the same problem in the next extruder switch from T1 to T0, thereby snowballing into layer switches taking longer and longer.
2016-06-28 13:59:29 +02:00
Ghostkeeper 7e12817974 Codestyle: Spaces after comma
Contributes to issue CURA-1506.
2016-06-28 13:05:34 +02:00
Tim Kuipers 93bf338ff2 fix: start heating one second earlier (CURA-1731) 2016-06-28 12:14:42 +02:00
Jaime van Kessel 48c6b2a058 Merge branch 'feature_zhop_over_other_material' of github.com:Ultimaker/CuraEngine 2016-06-28 11:35:22 +02:00
Tim Kuipers e132db6142 codestyle: brackets (CURA-1506) 2016-06-27 18:09:51 +02:00
Tim Kuipers a0536af848 fixup: more consts in PolygonUtils::moveInside2 (CURA-1506) 2016-06-27 18:05:31 +02:00
Tim Kuipers 8e8c7fcfc9 doc: more documentation in combing (CURA-1506) 2016-06-27 18:01:45 +02:00
Tim Kuipers 6d672cc840 refactor: over_unavoidable_obstacles_makes_combing_fail ==> fail_on_unavoidable_obstacles (CURA-1506) 2016-06-27 17:49:01 +02:00
Tim Kuipers 9bf8dbbc96 fix: pass down penalty_function through PolygonUtils::ensureInside and moveInside2 (CURA-1506) 2016-06-27 17:42:25 +02:00
Tim Kuipers c1d4ba89d2 lil: removed unused code in unit test (CURA-1506) 2016-06-27 17:19:39 +02:00
Tim Kuipers 58269b363c Merge branch 'feature_zhop_over_other_material' of https://github.com/Ultimaker/CuraEngine into feature_zhop_over_other_material 2016-06-27 17:13:36 +02:00
Ghostkeeper a2f6e62795 Codestyle: Brackets around indented blocks
Contributes to issue CURA-1506.
2016-06-27 16:42:48 +02:00
Tim Kuipers 1e1a7e4f95 refactor/fix: removed retraction_config from GCodePathConfig and removed all last_retraction_config logic to revert to just using the retraction config of the extruder (CURA-303) 2016-06-27 15:02:05 +02:00
Ghostkeeper b035b47526 Spelling fix in documentation
Contributes to issue CURA-1506.
2016-06-27 14:47:14 +02:00
Ghostkeeper 53eda52041 Remove trailing whitespace
Contributes to issue CURA-1506.
2016-06-27 14:37:40 +02:00
Tim Kuipers 52331d0c83 fix: skin areas were missing when alternate extra perimeter was enabled (CURA-1773) 2016-06-27 10:43:55 +02:00
Tim Kuipers 5cc85d3bf6 fix: no more configurable switch_extruder_retraction_hop (CURA-1506 CURA-1061)
making the height configurable is quite difficult with how retraction currently works and there is not a lot of added value
2016-06-24 15:25:00 +02:00
Tim Kuipers 7cf21e9926 fix unit test: GCodePlannerTest::computeNaiveTimeEstimatesRetractionTest() (CURA-1061) 2016-06-24 15:04:10 +02:00
Tim Kuipers 26d506a0f4 refactor/fix: move extruder switch retraction config to sliceDataStorage so that extruder switch z hop can be applied (CURA-1061) 2016-06-24 15:03:43 +02:00
Tim Kuipers 607c21ee46 fix: extruder switch zhop not performed on layer start anymore (CURA-1061)
only when the layer starts with a different extruder as the previous ended with
2016-06-24 14:18:55 +02:00
Tim Kuipers 402ede10d4 fix: perform zhops on very first travel of extruder plan. (CURA-1061)
still buggy: Now it does a zhop also on the start of a layer
2016-06-24 14:04:36 +02:00
Tim Kuipers bdd86ab9aa fix: made max_crossing_dist2 smaller cause other material was being crossed (CURA-1506) 2016-06-23 23:48:01 +02:00
Tim Kuipers ab3b1c2320 removed assert which doesn't seem to be true given the updated description of PolygonUtils::ensureInsideOrOutside(.) (CURA-1506) 2016-06-23 23:27:53 +02:00
Tim Kuipers 85e2ecc87e doc: warning for polygonUtils::ensureInsideOrOutside(.) that it may give false positives (CURA-1506) 2016-06-23 23:26:14 +02:00
Tim Kuipers 82846c0cc2 debug: PolygonUtils::ensureInsideOrOutside(.) does a polygon offset which sometimes seems to fail (CURA-1506)
sometimes it results in too small polygons which clipper itself and we cannot handle.
sometimes very small polygons are offsetted to polygons which lie outise the original polygon.
2016-06-23 23:25:20 +02:00
Tim Kuipers 09015e188a lil SVG const correctness 2016-06-23 23:06:23 +02:00
Tim Kuipers 36dbcfc667 check: assert to see whether ensureInsideOrOutside really moved inside (CURA-1506) 2016-06-23 22:56:34 +02:00
Tim Kuipers 5db83799d2 fix: PolygonUtils::ensureInsideOrOutside(.) checks is_inside to see if polygon offset failed (CURA-1506) 2016-06-23 22:55:54 +02:00
Tim Kuipers 9cb04d9e7a SVG fix for font size 2016-06-23 22:46:47 +02:00
Tim Kuipers 1c966cb6a5 deleted ancient test.cpp 2016-06-23 22:45:05 +02:00
Tim Kuipers f4d7695700 fix: replaced PolygonRef::inside(.) by Clipper function (CURA-1506) 2016-06-23 22:44:18 +02:00
Tim Kuipers 2288d2da49 fix: combing fails instead of crashes when combing fails due to too thin parts (CURA-1506) 2016-06-23 17:14:57 +02:00
Tim Kuipers 5d5a02739c fix: moveInside failed when distance was more than max_dist, but it was already inside anyway (CURA-1506) 2016-06-23 17:11:06 +02:00
Tim Kuipers 9248c17ace fix: combing findCrossingInOrMid can fail when part is too small (now doesn't crash anymore) (CURA-1506) 2016-06-23 16:46:35 +02:00
Tim Kuipers 7417e7d674 fix: Comb::moveInside forgot to set the inside_poly output parameter (CURA-1506) 2016-06-23 16:45:09 +02:00
Tim Kuipers 58228ff9a6 fix: PolygonUtils::findClose etc functions are now safe wrt ClosePolygonPoints which are not found (CURA-1506) 2016-06-23 16:18:44 +02:00
Tim Kuipers 329199af15 feat/fix: combing: findCrossingInOrMid now ensures to be inside (CURA-1506) 2016-06-23 16:17:39 +02:00
Tim Kuipers 2aa67efa20 refactor: changes ClosestPolygonPoint::point_idx and poly_idx to _unsigned_ int (CURA-1506)
NO_INDEX is an unsigned int and we don't need to waste all negative numbers which are invalid anyway
2016-06-23 15:47:37 +02:00
Tim Kuipers 7b79debf9a feat/fix: combing: moveInside now ensures to be inside, or changes startInside / endInside (CURA-1506) 2016-06-23 15:46:24 +02:00
Tim Kuipers 1314f00713 test: unit tests for PolygonUtils::ensureInside and for moveInside2 (CURA-1506) 2016-06-23 15:36:57 +02:00
Tim Kuipers a407ea6b61 fix: PolygonUtils::ensureInsideOrOutside passed output parameter by value (CURA-1506)| 2016-06-23 15:13:01 +02:00
Tim Kuipers 02e22b9442 small fixes in PolygonUtils (CURA-1506) 2016-06-23 14:47:17 +02:00
Tim Kuipers 5062a985fe feat: PolygonUtils::ensureInsideOrOutside more rigorous than a simple moveInside (CURA-1506) 2016-06-23 14:46:41 +02:00
Tim Kuipers 5294ea508c refactor: const correctness in PolygonUtils (CURA-1506) 2016-06-23 14:45:27 +02:00
Tim Kuipers 286a6edaa4 feat: PolygonUtils::moveInside2 a more simple version of moveInside and also for single polygons (CURA-1506) 2016-06-23 14:43:49 +02:00
Tim Kuipers 6af8a8eb85 feat: polygon::offset(.) (CURA-1506) 2016-06-23 14:36:21 +02:00
Tim Kuipers ee38f51af8 refactor: ClosestPolygonPoint::pos ==> point_idx (CURA-1506) 2016-06-23 12:09:22 +02:00
Tim Kuipers 7428a47344 unit test: polygon offset on holes works the same as offset on outer boundary (CURA-1506) 2016-06-23 12:07:17 +02:00
Tim Kuipers b859327bbd refactor/feat: ClosestPolygonPoint now also includes the poly index of the polygon which it refers to (CURA-1506) 2016-06-23 12:06:21 +02:00
Tim Kuipers 0a02a140fb fix: combing: better findInOrMid for tiny segments (CURA-1506) 2016-06-22 18:01:15 +02:00
Tim Kuipers 5d2d1fe6f3 lil fix: combing: made a small crossing more important than a large detour, cause otherwise sometimes combing fails because of it (CURA-1506) 2016-06-22 17:41:12 +02:00
Tim Kuipers ed2cdfa67a lil debug svg constness 2016-06-22 17:17:43 +02:00
Tim Kuipers 6d22cceac5 fix: Polygonutils::findClose only checked vertices of from-poly, now also checks points on line segments (CURA-1506) 2016-06-22 17:17:12 +02:00
Tim Kuipers 8a9f7dbf2b fix: use last_retraction_config for retractions (CURA-1506) 2016-06-22 17:16:32 +02:00
Ghostkeeper aa5bc6385b Merge branch 'materials_test' 2016-06-22 15:32:22 +02:00
Ghostkeeper 764d9868c7 Take max of double+double, not int+double
Not properly overloaded by max, I think.

Contributes to issue CURA-1717.
2016-06-22 15:32:07 +02:00
Ghostkeeper 5153022d28 Merge branch 'materials_test' 2016-06-22 15:28:42 +02:00
Ghostkeeper 7d87d2baea Improve time estimate when accelerating wrong way
When accelerating the wrong way, the discriminant of this parabolic is negative. Instead of returning a time estimate of 0, return the extremum of the parabola.

Contributes to issue CURA-1717.
2016-06-22 15:24:58 +02:00
Tim Kuipers 14518007a4 refactor: GCodePlanner::last_retraction_config ==> last_planned_retraction_config (CURA-1506 CURA-958) 2016-06-22 14:38:05 +02:00
Tim Kuipers 64f69d7629 fix: writeRetraction refered to last *planned* retraction config AND removed functionality to make a retraction into the extruder switch retraction (CURA-1506 CURA-958)
The only function using the last_retraction_config was the function which owuld convert a normal retraction into a nozzle switch retraction, instead of first performing the normal retraction and then the nozzle switch retraction. That functionality had to be removed anyway, because performing the nozzle switch retraction on the print can leave more scarring.
2016-06-22 14:34:42 +02:00
Tim Kuipers c93facc43c fix combing: moveInside always returned false even if we found a point inside (CURA-1506) 2016-06-21 18:09:49 +02:00
Tim Kuipers c2144cfe1c fix: PolygonUtils::moveInside tackled the corner case wrong when the point was exactly on the last point of a polygon (CURA-1506) 2016-06-21 17:32:55 +02:00
Tim Kuipers ca2b4af6f7 fix combing: move inside from previous move inside try so we can get out of the tip of a narrow angled piece (CURA-1506)
also I fixed that moveInside always made inside true, when it was false before.
2016-06-21 17:31:58 +02:00
Tim Kuipers 4d429eb719 fix: combing: better move inside strategy (CURA-1506) 2016-06-21 16:53:41 +02:00
Tim Kuipers e76109697e refactor: move combings moveInside into its own function (CURA-1506) 2016-06-21 16:01:17 +02:00
Tim Kuipers 213b67528a lil debug fix to SVG 2016-06-21 14:13:59 +02:00
Tim Kuipers 162d9aa0f7 fix: combing used offset_outside instead of distance between inside and outside at some places (CURA-1506) 2016-06-21 14:13:33 +02:00
Tim Kuipers 1c8f859885 fix: max_crossing_dist only accounted for the outside_boundary offset, not the inside_boundary_offset (CURA-1506) 2016-06-20 18:02:41 +02:00
Tim Kuipers db4c9b63f8 fix: combing: find better crossing when crossing diagonally between vertices (CURA-1506) 2016-06-20 18:02:02 +02:00
Javier Lechuga cc349cd046 bugfix_SegfaultDeletedCString 2016-06-20 17:34:57 +02:00
Tim Kuipers 6a925b73d6 lil doc 2016-06-20 17:25:23 +02:00
Tim Kuipers 2290a0927d refactor: moved Comb::findBestCrossing into Crossing (CURA-1506)
also used the same close_to for finding the crossing with the least detour, which is technically a change, but practically does the same thing.
2016-06-20 17:14:25 +02:00
Tim Kuipers 297a22280d refactor: combing crossings calculated factored out to new class Crossing (CURA-1506) 2016-06-20 17:11:25 +02:00
Javier Lechuga cd98c620af Merge branch 'bugfix_wallcount0' 2016-06-20 16:22:49 +02:00
Tim Kuipers e9647413f8 lil fix: polygon::PartsView::asseblePart is now const (CURA-1506) 2016-06-20 15:41:51 +02:00
Javier Lechuga 998ed5a76c bugfix: wall line count 0. CURA-1467 2016-06-20 14:39:23 +02:00
Tim Kuipers 2d62e67a24 refactor: moved combing classes into separate files (CURA-1506) 2016-06-20 13:18:46 +02:00
Tim Kuipers 69d2ab837f refactor: moved Comb into dir pathPlanning (CURa-1506) 2016-06-20 12:23:48 +02:00
Ghostkeeper ab8f84aa2d Merge branch 'materials_test' 2016-06-17 17:57:04 +02:00
Ghostkeeper 72c0a8391b Fix time estimates with accelerations
This was giving NaN values in the time estimates for the edge case where the discriminant of this quadratic was actually 0.0, but due to floating point rounding errors ended up below 0.

Contributes to issue CURA-1717.
2016-06-17 17:56:30 +02:00
Tim Kuipers 4b9a79df4d fix: combing: scanline crossings edge case for line segments ending exactly on the scanline (CURA-1506) 2016-06-17 17:51:01 +02:00
Tim Kuipers f7decf86a2 fix: combing can now fail if moving too far over in_between (CURA-1506) 2016-06-17 15:25:39 +02:00
Tim Kuipers 61b735ce89 fix: combing used pointer to local variable (CURA-1506) 2016-06-17 15:21:44 +02:00
Tim Kuipers c4b78fdfd1 fix: perform z hop always when not combing (CURA-1506)
whether to perform a z hop only when the comb move would collide only influences when the combing calculation decides to fail
2016-06-17 14:38:39 +02:00
Tim Kuipers 96769cb90c fix: combing: early calculation stopping for z-hops (CURA-1506) 2016-06-17 14:32:42 +02:00
Tim Kuipers 0ee60d2d3a fix: return whether the combing crosses an inavoidable boundary, aka being locked in/out (CURA-1506) 2016-06-17 14:01:05 +02:00
Tim Kuipers 9cbbdad56f lil: made clear where endInside and startInside are finally computed (CURA-1506) 2016-06-17 13:58:18 +02:00
Tim Kuipers 4a18f5d03d fix: combing: optimized and fixed going via hole polygon when endpoint is inside of the part containing the start point (CURA-1506) 2016-06-17 13:56:57 +02:00
Tim Kuipers 9b76a2e820 fix: combing/avoid always went to outside of part even when the endpoint was inside of a hole in the start part (CURA-1506) 2016-06-17 12:36:19 +02:00
Tim Kuipers 5a1897d631 feat: SVG::writePolygons and better border handling 2016-06-17 12:31:54 +02:00
Tim Kuipers 9d83fe08d8 doc: more documentation on combing and scanline crossings (CURA-1506) 2016-06-17 12:30:44 +02:00
Tim Kuipers 428198b4f9 feat: combing: find crossing from in to out closer to end point (CURA-1506) 2016-06-16 16:44:53 +02:00
Tim Kuipers e92bf03293 feat: combing: prefer crossings closer to start/end point a bit more (CURA-1506) 2016-06-16 16:33:13 +02:00
Tim Kuipers 9fe77a5761 test: PolygonUtils::findClose with penalty_function (CURA-1506) 2016-06-16 16:19:21 +02:00
Tim Kuipers fa07addba2 feat: PolygonUtils::findClose now support a penalty_function (CURA-1506) 2016-06-16 16:19:00 +02:00
Tim Kuipers ba4e4cc38f fix: PolygonUtils::findClose would return nothing when first arbitrary point was best (CURA-1506) 2016-06-16 16:17:45 +02:00
Tim Kuipers e2a47e1619 fix: pass by value bug and doc (CURA-1506) 2016-06-16 15:53:24 +02:00
Tim Kuipers e107626026 unit test: Polygonutils::findClosest with penalty function (CURA-1506) 2016-06-16 15:36:35 +02:00
Tim Kuipers 527b1f9b13 feat: added optional penalty function to PolygonUtils::findClosest (CURA-1506) 2016-06-16 15:27:10 +02:00
Tim Kuipers 6abc896bab feat: perform z-hop only when combing fails (CURA-1506) 2016-06-16 15:00:20 +02:00
Tim Kuipers f2de0fd5df refactor/feat: introduced getLastPlannedExtruderTrainSettings and replaced code with that function and with getExtruder() (CURA-1506) 2016-06-16 14:59:45 +02:00
Johan K c202d1b47a Changed the message used to send the final slice result to the front-end to LayerOptimized
Corrected the name of the data from polygon to path segment and left the old message for future visualization of the earlier stages.
2016-06-16 00:10:43 +02:00
Tim Kuipers d4349818b7 fix: reset acceleration and jerk back to default firmware values afterwards (CURA-1443) 2016-06-16 00:02:17 +02:00
Tim Kuipers ce80ceb165 lil doc typo 2016-06-15 23:21:27 +02:00
Tim Kuipers d19310ee27 refactor: removed superfluous/old writeTypeComment(string ..) (CURA-1350) 2016-06-15 23:20:30 +02:00
Tim Kuipers 63e6a249e3 feat: write time estimates in comments every layer (CURA-1350) 2016-06-15 23:17:50 +02:00
Johan K 0b05457fac Adding polygon packing feature and change the structure of the layer data sent to the front-end to speed up the layer view 2016-06-14 18:20:01 +02:00
Tim Kuipers 63356dca41 feat: set firmware values from configuration (CURA-1646) 2016-06-14 17:05:14 +02:00
awhiemstra 4bce36550f Merge pull request #353 from Johan3DV/master_polyutil_ref
Adding some references
2016-06-14 10:35:40 +02:00
Johan K 3ca1e6673f Adding some missing references 2016-06-13 22:07:31 +02:00
Ghostkeeper b2a4ee1647 Merge pull request #350 from thopiekar/master-windows-work
Ignore generated Makefile and archives of code
2016-06-13 00:35:31 +02:00
Thomas Karl Pietrowski 81ef194164 Merge remote-tracking branch 'refs/remotes/Ultimaker/master' into master-windows-work 2016-06-11 12:40:24 +02:00
Thomas Karl Pietrowski 2c698c8ba0 Ignore generated Makefile and archives of code 2016-06-11 12:40:20 +02:00
Jaime van Kessel 54e63de3a8 Merge branch 'feature_accelerations_and_jerk_per_feature_settigns_rework' of github.com:Ultimaker/CuraEngine 2016-06-10 15:36:52 +02:00
Tim Kuipers 0186d35372 fix: retrieved extruder_count instead of machine_extruder_count (CURA-1560) 2016-06-10 15:21:14 +02:00
Tim Kuipers c018a44c38 fix: retrieved extruder_count instead of machine_extruder_count (CURA-1560) 2016-06-10 13:13:13 +02:00
Tim Kuipers 0c62d1ab65 Merge branch 'master' into feature_accelerations_and_jerk_per_feature_settigns_rework 2016-06-10 12:19:41 +02:00
Tim Kuipers ff1fca976e bugfix: global settigns were never loaded (CURA-1682) 2016-06-09 19:03:52 +02:00
Tim Kuipers a7ad42eb1f fix: bugfix in comandSocket Extruder.settings (CURA-1682) 2016-06-09 13:10:30 +02:00
Tim Kuipers fb526ffc6d lil doc (CURA-1682) 2016-06-09 12:13:08 +02:00
Tim Kuipers d806c23d59 feat: handle extruder train settings (CURA-1682) 2016-06-09 12:07:24 +02:00
Tim Kuipers 28b8b41475 Added extruder to proto message
CURA-1681
CURA-1682
2016-06-09 12:00:35 +02:00
Tim Kuipers 457e609091 refactor/bugfix: inline handleSettingList (CURA-1682)
Two commits above introduced a bug where I passed thw wrong objects to handleSettingList
2016-06-09 11:40:50 +02:00
Tim Kuipers ffcd076f3e doc: commented proto file (CURA-1682 CURA-1681) 2016-06-09 11:39:11 +02:00
Tim Kuipers 01951ac513 feat: global settings are now passed via the same message as the objects (CURA-1682) 2016-06-09 11:08:36 +02:00
Tim Kuipers a8debfde40 refactor: comandSocket::handleSettingList now takes a settings base (CURA-1682) 2016-06-09 11:06:51 +02:00
Tim Kuipers 3194e30772 Updated proto file
Objects & global settings are now sent in one message.
    Also added support for extruder settings

    CURA-1681
CURA-1682
2016-06-09 10:50:46 +02:00
Tim Kuipers 223313c5ef Merge pull request #349 from thopiekar/master-windows-work
Adding generated CMake files to .gitignore
2016-06-08 15:18:17 +02:00
Thomas Karl Pietrowski 5a8f580edd Adding generated CMake files to ignore
These files are generated by CMake on Windows 10 64bit with Visual
Studio installed. They are not tracked by the project, so they can be
savely removed by git clean.
2016-06-08 13:50:59 +02:00
Tim Kuipers 394fbda0ff lil codestyle 2016-06-08 12:12:42 +02:00
Tim Kuipers e778cc6bf0 Merge branch 'master' of https://github.com/Ultimaker/CuraEngine 2016-06-08 10:38:09 +02:00
Tim Kuipers af6b581167 lil doc 2016-06-08 10:36:34 +02:00
Tim Kuipers 2f026d006c fix: mergeInfillLines had a boolean mistake due to 497c969 (CURA-1560) 2016-06-08 10:33:15 +02:00
Tim Kuipers 86daf598e5 fix: minimal avoid distance is zero (CURA-1560) 2016-06-08 10:30:42 +02:00
Tim Kuipers e77ddee5de fix: put back the *2 I accidentally removed in ee087f23 (CURA-1560) 2016-06-08 09:58:09 +02:00
Tim Kuipers 162fac057d fix: support_type was retrieved per mesh instead of globally (CURA-1560) 2016-06-08 09:55:25 +02:00
Thomas Karl Pietrowski 5c3c038c43 Merge remote-tracking branch 'refs/remotes/Ultimaker/master' 2016-06-08 09:41:58 +02:00
Tim Kuipers 78432b49fe Update README.md 2016-06-07 16:06:18 +02:00
Tim Kuipers 4395f9a465 fix: only force minimal layer time on the last extruder plan (CURA-1568) 2016-06-06 17:37:37 +02:00
fieldOfView 0288f08cc3 Fixes for codestyle and find/replace accident
CURA-967
2016-06-05 15:28:45 +02:00
Tim Kuipers beb14b3e15 fix: machine_extruder_end_pos_abs was retrieved globally (CURA-1568) 2016-06-03 17:30:38 +02:00
Tim Kuipers c436a108ec fix: dynamic char array size instead of static (CURA-1574)
A static char array length is open to buffer overflow problems/attacks
2016-06-03 17:04:51 +02:00
Tim Kuipers 5f9bfb6ac5 fix: cool_lift_head is now retrieved per meshgroup (CURA-1568) 2016-06-03 17:00:16 +02:00
Tim Kuipers 43a69544fb fix: handleAllRemainingInserts at the very end of an extruder plan (CURA-1568) 2016-06-03 16:37:40 +02:00
Tim Kuipers a53141089c indent fix (CURA-1568) 2016-06-03 16:36:55 +02:00
Tim Kuipers 57a58afc7a fix: don't lift head if we are at the switching bay (CUTA-1568) 2016-06-03 16:36:31 +02:00
Tim Kuipers 2e9f712eae indent: fixed indentation (CURA-1568) 2016-06-03 16:13:29 +02:00
Tim Kuipers 075b3e6581 refactor/feat: move fanSpeedLayerTime computation inside the ExtruderPlan class (CURA-1568) 2016-06-03 16:12:26 +02:00
Tim Kuipers 8c4c2bae67 refactor: fan_speed_layer_time_settings_per_extruder.emplace_back (BUGGY STATE) (CURA-1568) 2016-06-03 16:10:55 +02:00
Tim Kuipers 8318f290fa fix: better GCodePlannerTest (CURA-1560) 2016-06-03 13:13:28 +02:00
Tim Kuipers 191f699309 fix: testcase GCodePlannerTest restored (CURA-1560) 2016-06-03 13:09:32 +02:00
Tim Kuipers 2dac16b44f refactor: remove unnecessary argument parent_file from SettingRegistry::getDefinitionFile (CURA-1574) 2016-06-03 12:47:32 +02:00
Tim Kuipers 9db735e2e5 fix: record search paths for extruder train defs (CURA-1574) 2016-06-03 12:44:18 +02:00
Tim Kuipers ee087f23de fix: wall_line_width/count not retrieved per extruder anymore (CURA-1560) 2016-06-03 00:02:50 +02:00
Tim Kuipers 5878916b03 fix: retrieve travel_avoid_distance per extruder and use the highest value (CURA-1560) 2016-06-02 23:24:24 +02:00
Tim Kuipers 7e7dbf34be refactor: rename some vars from storage ==> mesh (CURA-1560) 2016-06-02 23:02:14 +02:00
Tim Kuipers c3d535d88f fix: adhesion_type was retrieved per mesh (CURA-1560) 2016-06-02 22:59:49 +02:00
Tim Kuipers 2b987a9a73 DEBUG: commented a whole testcase (CURA-1560) 2016-06-02 22:53:18 +02:00
Tim Kuipers 315f01daef refactor: removed global retrieval of travel config (CURA-1560) 2016-06-02 22:50:26 +02:00
Tim Kuipers fdc756a22b refactor: moved sliceDataStorage initialization to header file (CURA-1560) 2016-06-02 22:28:46 +02:00
Tim Kuipers 497c969048 refactor: removed global travel config (CURA-1560) 2016-06-02 22:23:07 +02:00
Tim Kuipers e22d4d30e7 refactor: removed global retraction config (CURA-1560) 2016-06-02 21:40:22 +02:00
Tim Kuipers 432761690b fix: removed (globally retrieved) travel speed dependancy from finalize (CURA-1560) 2016-06-02 18:25:23 +02:00
Tim Kuipers 39422e6dbc fix: platform adhesion options now all retrieved from extruder train (CURA-1560) 2016-06-02 18:22:23 +02:00
Tim Kuipers 0f9c14e42a fix: temps set multiple times and temps retrieved per mesh (CURA-1560) 2016-06-02 17:29:22 +02:00
Tim Kuipers d9374270cf fix: magic_spiralize was retrieved globally (CURA-1560) 2016-06-02 17:10:28 +02:00
Tim Kuipers 9f8cdf69f0 fix: layer_height was retrieved per mesh (CURA-1560) 2016-06-02 17:04:15 +02:00
Tim Kuipers 492e4f7b29 fix: machine_name was never actually loaded in the settings (CURA-1574) 2016-06-01 17:19:59 +02:00
Tim Kuipers b50bc938df lil refactor 2016-06-01 15:58:40 +02:00
Tim Kuipers aa36ad175e fix: overlaps were compensated twice when layer would start within an overlap zone (CURA-1635) 2016-06-01 15:56:58 +02:00
Tim Kuipers 0d50fe50b4 fix: heuristic solution to circumvent iterator invalidation (CURA-1635)
complex models with almost everywhere pieces smaller than twice the nozzle width could break the heuristic, when there are a lot of 3-way intersections of thin walls
2016-06-01 15:54:52 +02:00
Tim Kuipers 8bf31f771c refactor: moved WallOverlapComputation constructor to cpp file (CURA-1635) 2016-06-01 13:47:25 +02:00
Tim Kuipers 634fddd908 lil doc 2016-06-01 13:32:24 +02:00
Tim Kuipers 7f64494dec lil refactor (CURA-1635) 2016-06-01 13:27:10 +02:00
Tim Kuipers dffb1ef459 doc: lil doc for walloverlap comp (CURA-1635) 2016-06-01 13:22:43 +02:00
Tim Kuipers 9b74c6c0a2 better debugging for wallOverlapComp 2016-06-01 13:21:44 +02:00
Tim Kuipers b23ede94f3 lil debug fix for WallOverlapComputation 2016-06-01 11:53:27 +02:00
Tim Kuipers 1837d658dd fix: infill_area_per_combine wasn't always filled (CURA-1255) 2016-05-31 15:27:30 +02:00
Tim Kuipers 7086762216 refactor: early out for polygon settings (which are unsupported) (CURA-1574) 2016-05-31 12:43:04 +02:00
Tim Kuipers bc78163d70 fix: settings default values got deleted when overriden by json object which didn't define a default_value (CURA-1574) 2016-05-31 12:41:56 +02:00
Tim Kuipers 81c2091ddb lil fix in help (CURA-1574) 2016-05-30 17:05:07 +02:00
Tim Kuipers 6e3d71e39b fix: load machine_extruder_trains ids from machine definition after the recursion, so that the parent json file doesn't overload the current (CURA-1574) 2016-05-30 17:02:27 +02:00
Tim Kuipers 35112600bc fix: dont warn for duplicated for non-base files and for extruder trains (CURA-1574)
extruder train base definition file gets loaded for each extruder, and we don't want to get duplicate errors every time we load the second extruder
2016-05-30 17:00:29 +02:00
Tim Kuipers 0e58fb960f feat: load extruder train defaults (and definitions) on creation of new extruder train (CURA-1574) 2016-05-30 16:44:42 +02:00
Tim Kuipers a36c90d076 clenaup: removed unused function in settingsRegistry (CURA-1574) 2016-05-30 16:36:10 +02:00
Tim Kuipers b72625b28f feat: settingsRewgistry::loadExtruderJSONsettings (CURA-1574) 2016-05-30 16:35:44 +02:00
Tim Kuipers 8ead13d2be cleanup: removed old extruder_trains unused default saving mechanism (CURA-1574) 2016-05-30 16:27:31 +02:00
Tim Kuipers d30d2af4f0 feat: remember extruder train ids from json (CURA-1574) 2016-05-30 16:20:46 +02:00
Tim Kuipers 6808e25cd8 Merge branch 'feature_accelerations_and_jerk_per_feature_settigns_rework' of https://github.com/Ultimaker/CuraEngine into feature_accelerations_and_jerk_per_feature_settigns_rework 2016-05-30 15:18:22 +02:00
Tim Kuipers cdc2d17455 fix: spiralzie got reintroduced by merge with code which moved GCodePathConfig (CURA-1443) 2016-05-30 15:17:18 +02:00
Tim Kuipers 31dbc4ef24 Merge branch 'feature_accelerations_and_jerk_per_feature' into feature_accelerations_and_jerk_per_feature_settigns_rework 2016-05-30 15:16:11 +02:00
Tim Kuipers 01c78d555c Merge branch 'feature_accelerations_and_jerk_per_feature' into feature_accelerations_and_jerk_per_feature_settigns_rework 2016-05-30 15:12:31 +02:00
Tim Kuipers 2f46c0e473 fix: make path delimiter depend on OS (CURA-1574) 2016-05-30 11:27:54 +02:00
Tim Kuipers 34f60e6616 lil codestyle 2016-05-30 11:08:41 +02:00
Tim Kuipers 303246b39c fix: generateMultipleVolumesOverlap was broken (CURA-833) 2016-05-27 13:45:10 +02:00
Tim Kuipers 3b80ac93ea lil prime tower fix 2016-05-27 13:30:16 +02:00
Tim Kuipers 6b7b5a7ea9 refactor: load setting defaults into settings at the moment they get loaded (CURA-1574) 2016-05-27 13:27:48 +02:00
Tim Kuipers 231eee1e46 lil prime tower fix 2016-05-27 13:26:25 +02:00
Tim Kuipers 81424528f3 refactor: no more overload_defaults_only (CURA-1574) 2016-05-27 13:00:17 +02:00
Tim Kuipers c78808b69d lil 2016-05-27 12:59:37 +02:00
Tim Kuipers 1c347be3be fix: don't overload defaults only when loading extruder json files (CURA-1574) 2016-05-27 12:53:38 +02:00
Tim Kuipers c79c503621 fix: setting loading always segfaulted (CURA-1574) 2016-05-26 21:01:49 +02:00
Tim Kuipers e6fb617f3f refactor: simplified SettingRegistry::handleSetting (CURA-1574) 2016-05-26 08:46:37 +02:00
Tim Kuipers ca1799efc6 remove unneeded function (CURA-1574) 2016-05-26 08:46:13 +02:00
Tim Kuipers 749e85b15b doc: setting registry stuff (CURA-1574) 2016-05-26 08:45:50 +02:00
Tim Kuipers 82c7bfaf7a fix: don't retrieve settings from registry (CURA-1574)
The settings are set during the loading of the json file, not during retrieval of settings
2016-05-25 17:08:54 +02:00
Tim Kuipers d5df34b3cf fix: don't set extruder train defaults anymore via some special casing for extruder trains (CURA-1574) 2016-05-25 17:07:35 +02:00
Tim Kuipers 59774e7f14 lil: less warnings when handling json (CURA-1574)
warnings were given twice and were given for overriding frontend settings
2016-05-25 17:05:36 +02:00
Tim Kuipers bf8e73a4ae feat: load json setting default directly into a given settings base (CURA-1574)
Instead of keeping the defaults in the global settings registry, load the defaults immediately into a settings base, so that we can override the extruder train defaults.
2016-05-25 16:58:41 +02:00
Tim Kuipers 8b778b82be fix: support_extruder_nr used instead of support_infill_extruder_nr 2016-05-25 15:28:25 +02:00
Tim Kuipers d42b0ac9eb fix: SettingsToGv for new setting json files (CURA 1574) 2016-05-25 15:27:11 +02:00
Tim Kuipers cda656d43d lil: made etDefinitionFile static (CURA-1574) 2016-05-25 15:02:55 +02:00
Tim Kuipers 8c18b2ca89 fix doc: help and README show new way of handling settings and the CURA_ENGINE_SEARCH_PATH env var (CURA-1574) 2016-05-25 15:01:56 +02:00
Tim Kuipers eeb69776de feat: load json settings recursively and check in paths provided in CURA_ENGINE_SEARCH_PATH (CURA-1574) 2016-05-25 14:46:08 +02:00
Tim Kuipers cee01abe16 refactor: pass down warn_duplicates via setting calls (CURA-1574)
Extruder train definition .def.json files shouldn't warn for duplicates; only the base file should.
2016-05-25 12:30:49 +02:00
Tim Kuipers 8df1562d7b cleanup imports (CURA-1574) 2016-05-25 12:23:18 +02:00
Tim Kuipers 3bbc4a1d72 refactor: split settingRegistry into separate class and header files (CURA-1574) 2016-05-25 12:19:23 +02:00
Tim Kuipers 5a9eaa29ea refactor: move settings related files into separate folder (CURA-1574) 2016-05-25 12:07:59 +02:00
Tim Kuipers 6faeaf8c0b fix: accidental __cxx11:: in type (CURA-1574) 2016-05-20 14:04:46 +02:00
Tim Kuipers f9b15a2f47 refactor: settingsResistry.settings ==> setting_key_to_config (CURA-1574) 2016-05-20 12:58:02 +02:00
Tim Kuipers c1eb1fdd85 fix: forgotten newline in SettingContainer debug out (CURA-1574) 2016-05-20 12:57:27 +02:00
Tim Kuipers 324f424e69 refactor: simplified machine name loading (CURA-1574) 2016-05-20 12:51:04 +02:00
Tim Kuipers 3dfb35d73e fix: a settings container is now used only for the global settings base and for the separate extruder train settings default bases (CURA-1574) 2016-05-20 12:50:38 +02:00
Tim Kuipers e72789e3cb fix: read new setting .def.json files (CURA-1574)
Simplified the recursion of reading settings
Made the settings registry into a flat list, rather than a tree
Made each setting record a path instead (to keep the same information as the tree)
Moved extruder trains into a separate object, rather than it being a normal category
warn_duplicates strategy simplified: always after the first file
(rather than when applying overrides)
temporarily removed reading of machine_extruder_trains
made label attribute obligatory
Always add a setting to the global setting config (cause reading machine_extruder_trains is currently not implemented)
2016-05-20 12:42:14 +02:00
Tim Kuipers d6ac9e69c1 lil 2016-05-19 17:08:02 +02:00
Tim Kuipers 358d2e26c2 lil 2016-05-19 17:07:04 +02:00
Tim Kuipers e9fb973a05 fix: machine_settings became just another category, so doesnt need special handling (CURA-1574) 2016-05-19 14:29:55 +02:00
Tim Kuipers 22b86f81b7 fix: don't load inheriting json document (CURA-1574)
The inherit property now refers to an id instead of a filename, so I cannot simply know which file I have to load from a given json file
2016-05-19 14:28:59 +02:00
Tim Kuipers cf05c65061 lil: don't wait after priming second nozzle 2016-05-18 17:25:45 +02:00
Tim Kuipers 5f8f0110cf fix: switch infill direction every X layers (CURA-1569 CURA-943)
infill combine always prints infill of any thickness on infill of the first fully combined layer below
2016-05-18 16:35:10 +02:00
Tim Kuipers d3715e8e76 refactor: moved getSettingBoolean(cool_lift_head) inside gcodePlanner::writeGCode(.) (CURA-1568) 2016-05-18 13:36:05 +02:00
Tim Kuipers 31e2996104 refactor: removed superfluous layerThickness parameter to gcodePlanner::writeGCode(.) (CURA-1568) 2016-05-18 13:32:13 +02:00
Tim Kuipers 3ff329033a lil doc 2016-05-18 10:24:42 +02:00
Tim Kuipers f7d72623d2 fix: better naming for infill/skin overlap for support (CURA-967) 2016-05-13 13:22:34 +02:00
Tim Kuipers fee8867855 feat: skin_overlap separated from infill_overlap (CURA-967) 2016-05-13 13:22:04 +02:00
Tim Kuipers 62a4db8632 fix: initial layer thickness stays the same even when having a raft 2016-05-12 23:42:06 +02:00
Tim Kuipers efb20afc76 fix: only process if there's any non-infill meshes (CURA-833) 2016-05-12 20:49:46 +02:00
Tim Kuipers 683c887e53 fix: made generateMultipleVolumesOverlap ignore infill meshes and made overlap changable per object (CURA-883) 2016-05-12 20:11:00 +02:00
Tim Kuipers 4d9daccb5b fix: don't generateMultipleVolumesOverlap for infill meshes (CURA-833) 2016-05-12 20:06:25 +02:00
Tim Kuipers c0611904bb refactor: compute generateMultipleVolumesOverlap differently (CURA-833)
instead of for each layer computing overlap for all volumes, go through all volumes computing overlap for each layer
2016-05-12 20:04:03 +02:00
Tim Kuipers cecac0fe90 lil: code conventions (CURA-833) 2016-05-12 19:56:00 +02:00
Tim Kuipers f48c858ec4 fix: syntax fix of last merge 2016-05-12 19:55:34 +02:00
Tim Kuipers fc4d24fb01 optimization: carveMultipleVolumes uses aabb of meshes and discards infill meshes (CURA-1551 CURA-833) 2016-05-12 19:49:42 +02:00
Tim Kuipers 529301f950 Merge branch '2.1' 2016-05-12 19:25:10 +02:00
Tim Kuipers 33d2594b20 fix: M204 confirmed to too new Marlin standard (CURA-1443) 2016-05-12 16:54:22 +02:00
Tim Kuipers 9c47644e55 cleanup: removed fill_perimeter_gaps setting (CURA-996) 2016-05-12 16:30:11 +02:00
Tim Kuipers 2949f89b29 cleanup: removed perimeterGaps and functionality of fill_perimeter_gaps (CURA-996) 2016-05-12 16:28:39 +02:00
Tim Kuipers 1793961094 cleanup: removed avoidOverlappingPerimeters as parameters to functions and as member variables (CURA-996) 2016-05-12 16:22:34 +02:00
Tim Kuipers 590795921e cleanup: removed avoidOverlappingPerimeters and in_between from Infill factory (CURA-996) 2016-05-12 16:17:43 +02:00
Tim Kuipers b79c404dc3 remove: removed offsetSafe functions used for 'remove overlapping wall parts' (CURA-996) 2016-05-12 16:05:37 +02:00
Tim Kuipers 0065532d6d lil doc (CURA-996) 2016-05-12 14:00:09 +02:00
Tim Kuipers b89c8fd1fa fix: infill meshes didn't update bounding boxes (CURA-833) 2016-05-11 23:25:56 +02:00
Tim Kuipers d409c4d245 feat: infill_mesh_order to determine the order of infill meshes in eachother (CURA-833) 2016-05-11 23:25:28 +02:00
Tim Kuipers fd64b5ce60 fix: infill meshes updated infill_area, but not infill_are_per_combine (CURA-833) 2016-05-11 22:35:06 +02:00
Tim Kuipers 5bc3b86dc4 fix: infill meshes relied on old infill_area implementation (CURA-833) 2016-05-11 21:47:41 +02:00
Tim Kuipers 9ec92fa33f Merge branch 'feature_infill_mesh_correct_progress' 2016-05-11 21:43:58 +02:00
Tim Kuipers 03b654af3e feat: layer_0_z_overlap (CURA-1549) 2016-05-11 17:15:28 +02:00
Tim Kuipers e3c03e6c04 feat: switch_extruder_retraction_hop (CURA-1061) 2016-05-11 16:41:08 +02:00
Tim Kuipers 33c40f3398 Merge branch '2.1' 2016-05-11 13:27:16 +02:00
Tim Kuipers c79a7f1819 fix: spiralize would leave the z at the next layer for the next polygon on the same layer (CURA-1541) 2016-05-11 12:57:47 +02:00
Tim Kuipers 7843a68d7c lil: doc 2016-05-11 12:13:18 +02:00
Tim Kuipers 8f912835cf lil: doc indent 2016-05-11 12:11:37 +02:00
Tim Kuipers 36de33b735 fix: some small fixes of second last refactor (CURA-1367) 2016-05-11 12:07:24 +02:00
Tim Kuipers 01884663c3 refactor: rename files insets ==> WallsComputation (CURA-1367) 2016-05-11 12:04:11 +02:00
Tim Kuipers 4c46dd37a7 refactor: put generateInsets functions into a class (CURA-1367) 2016-05-11 12:01:16 +02:00
Tim Kuipers 9245a4fa41 fix: only compute print_outline when the mesh uses support (CURA-1367) 2016-05-11 11:50:31 +02:00
Tim Kuipers 4b240e8057 fix: let getLayerOutlines use an outline approximation based on the outer wall (CURA-1367)
Thin walls may be unprintable, so getLayerOutlines returns pieces of polygons which aren't actually printed.
This caused an edge overhang to remove support due to the XY distance of unprinted parts of the edge overhang.
When two parts are connected via an unprintably thin wall, also combing would be affected, but not anymore.
2016-05-11 11:36:38 +02:00
Tim Kuipers fff8195d51 Merge branch '2.1' 2016-05-11 08:52:55 +02:00
Tim Kuipers e01f18c7d4 lil: doc 2016-05-11 08:52:06 +02:00
Tim Kuipers 42891874f4 fix: multiple polygons & spiralize resulted in extrusions where travels should have been (CURA-1513) 2016-05-10 17:37:16 +02:00
Tim Kuipers 257d6a6635 fix: spiralize each polygon of a spiralized mesh even though that might cause a print head crash (CURA-1443) 2016-05-10 15:58:34 +02:00
Tim Kuipers bec8bef455 fix: consecutive spiralize paths are handled as one (CURA-1443 CURA-1541) 2016-05-10 15:32:09 +02:00
Tim Kuipers 4efeaa7083 fix: let bool spiralize bubble down from FffGcodeWriter into GCodePath instead of going via the GCodePathConfig (CURA-1443)
Because of the LayerPlanBuffer the GCodePathConfig changed a couple of layers too early, resulting in spiralization in the first layers which include the bottom skin.
2016-05-10 15:14:50 +02:00
Tim Kuipers 95fd9d6685 lil: doc 2016-05-10 13:25:11 +02:00
Tim Kuipers f6cf3356f8 feat: change time estimates based on jerk and acceleration (CURA-1443) 2016-05-10 09:38:06 +02:00
Tim Kuipers c041ca5ea1 fix: acceleration used wrong gcode (CURA-1443) 2016-05-10 09:33:42 +02:00
Tim Kuipers 92cb2f82ab refactor: moved firmware values inside TimeEstimateCalculator (CURA-1443) 2016-05-10 09:16:11 +02:00
Tim Kuipers fa7ff61bf5 feat: apply acceleration and jerk (CURA-1443) 2016-05-09 18:30:02 +02:00
Tim Kuipers 255c62782e feat: initial layer speedup also applied to acceleration and jerk (CURA-1443) 2016-05-09 17:14:58 +02:00
Tim Kuipers 9cbf760c80 feat: acceleration and jerk for GCodePathConfig (CURA-1443) 2016-05-09 15:27:47 +02:00
Tim Kuipers 506560e9e0 refactor: move path config parameters which change over layers into a separate struct (CURA-1443)
now the iconic settings and current settings are well separated, making it easier to introduce more settings which change over layers
2016-05-09 13:39:52 +02:00
Tim Kuipers d634e310fd refactor: moved GCodePathConfig implementation to new cpp file (CURA-1443) 2016-05-09 12:38:59 +02:00
Tim Kuipers 255dd4ffcd refactor: moved GCodePathConfig and RetractionConfig to their own header files (CURA-1443) 2016-05-09 12:34:47 +02:00
Tim Kuipers 6d54a31bcd Merge branch 'master' of https://github.com/Ultimaker/CuraEngine 2016-05-06 15:31:04 +02:00
Tim Kuipers 18df36ca06 refactor: moved AABB3D out of AABB (CURA-1436) 2016-05-06 15:30:22 +02:00
Tim Kuipers 55f47523b2 refactor: moved AABB implementation out of header file (CURA-1436) 2016-05-06 15:24:46 +02:00
Tim Kuipers 4130af0ad6 feat: boundingbox.expand (CURA-1436) 2016-05-06 15:06:19 +02:00
Tim Kuipers c08a0221c8 fix: combing basic comb path had wrong offsets to beginning and end of poly (CURA-1436) 2016-05-06 15:05:19 +02:00
Tim Kuipers 31f8459a0f Merge pull request #335 from sean041/patch-2
Compare in PolygonRef::shorterThan is strange.
2016-05-05 11:11:51 +02:00
Peng Liu 4642076fdc Compare in PolygonRef::shorterThan is strange.
PolygonRef::shorterThan will always return false?
2016-05-05 15:27:46 +08:00
Tim Kuipers 5fd3277919 doc&refactor: moved ConicalOverhang to cpp file (CURA-1412) 2016-05-04 15:34:06 +02:00
Tim Kuipers 13b3c715bf feat: compensate overlapping inner wlal parts (CURA-995) 2016-05-04 15:09:33 +02:00
Tim Kuipers 3583d71dcd lil: indent (CURA-1479) 2016-05-04 11:40:38 +02:00
Tim Kuipers c5ab004ece feat: option to apply different xy distance at overhang places (CURA-1479) 2016-05-04 11:40:15 +02:00
Tim Kuipers b8fe70ee74 feat: SupportDistPriority setting enum (CURA-1479) 2016-05-04 11:38:30 +02:00
Tim Kuipers 6db88290c2 lil debug 2016-05-03 15:57:55 +02:00
Tim Kuipers be6fd8cc7c fix: skirt was processed sometimes twice for the first extruder sometimes not at all for the second extruder (CURA-1446) 2016-05-03 15:57:40 +02:00
Tim Kuipers baeb736705 fix: if all layers got removed slicing didn't quit (CURA-1465) 2016-05-03 14:15:57 +02:00
Tim Kuipers 05fa05bb5a Merge branch 'master' of https://github.com/Ultimaker/CuraEngine 2016-05-03 13:51:33 +02:00
Tim Kuipers 5a7c2e5ef1 fix codestyle (tabs) 2016-05-03 13:50:33 +02:00
Tim Kuipers c9de58ceba fix: material used was logged on the wrong extruder (CURA-520) 2016-05-03 13:15:53 +02:00
Ghostkeeper 1d60079220 Merge branch 'feature_slicer_refactor_rebased' 2016-05-03 11:06:09 +02:00
Tim Kuipers 77d40fb0e9 fix: griffin header micron ==> mm (CURA-520) 2016-05-03 09:34:03 +02:00
Tim Kuipers 72e9906bb8 Merge branch '2.1' 2016-05-02 18:29:30 +02:00
Tim Kuipers 2db37c6018 fix: erase with impossible iterator when trying to simplify an empty polygon (CURA-1430) 2016-05-02 18:28:00 +02:00
Tim Kuipers 41b0966d26 fix: constructor prime tower called incorrectly 2016-05-02 17:33:00 +02:00
Ghostkeeper d5bff03a1c Codestyle: Space around binary operators
Contributes to issue CURA-520.
2016-04-29 16:18:59 +02:00
Tim Kuipers 0d5cc686c9 fix: exclude enum values from setting reflection 2016-04-29 14:32:07 +02:00
Tim Kuipers 3103acb7b0 fix: curaEngine analyse 2016-04-29 14:28:04 +02:00
Tim Kuipers bcce1bd8a4 feat:setting inheritance diagram 2016-04-29 14:27:50 +02:00
Tim Kuipers cda16c4429 Merge branch 'reflection_setting_inheritance_visualization' 2016-04-29 14:19:54 +02:00
Tim Kuipers 21a8afb895 fix: extruder train initialization M227 ==> G280 (CURA-520) 2016-04-28 17:05:32 +02:00
Tim Kuipers 0d7074ee8b doc: documented stuff in gcodePlanner.h (CURA-537) 2016-04-28 17:01:48 +02:00
Tim Kuipers 8bb91cecb9 fix: dont switch extruder if there is no priontable support (CURA-1437) 2016-04-28 15:49:30 +02:00
Tim Kuipers 7aaf3b9bae fix: dont switch extruder if there is no priontable model (CURA-1437) 2016-04-28 15:48:57 +02:00
Tim Kuipers a806a27836 fix: sometimes the first layer could be totally empty / no walls (CURA-1465) 2016-04-26 18:28:05 +02:00
Tim Kuipers d556999aed fix: jedi header: save json machine name as if it is a setting and retrieve it for the header (CURA-520) 2016-04-25 17:57:45 +02:00
Tim Kuipers 9da99b67fc fix: jedi header: PRINT.SIZE obtained from machine dimensions (CURA-520) 2016-04-25 17:15:55 +02:00
Tim Kuipers 4b02912ab6 fix: jedi header: BED ==> BUILD_PLATE (CURA-520) 2016-04-25 17:00:25 +02:00
Tim Kuipers 58234e4125 doc: Date documentation (CURA-520) 2016-04-25 16:45:21 +02:00
Tim Kuipers e825637f14 feat: jedi header includes date stamp (CURA-520) 2016-04-25 16:41:31 +02:00
Tim Kuipers 242384bd28 Merge branch 'feature_jedi_cura_starting_state' 2016-04-25 13:21:46 +02:00
Tim Kuipers b0cb94aeca Merge branch 'feature_slicer_refactor_rebased' of https://github.com/Ultimaker/CuraEngine into feature_slicer_refactor_rebased 2016-04-22 17:21:58 +02:00
Tim Kuipers 95fc4695d2 fix: polylines got copied, const correctness and documentation in slicer.cpp (CURA-738) 2016-04-22 17:19:51 +02:00
Tim Kuipers 1f6f847b51 lil: inlined one line of code 2016-04-22 16:19:03 +02:00
Tim Kuipers 3e1b5128bb lil: made polygon.shorterThan const (CURA-738) 2016-04-22 16:17:43 +02:00
Tim Kuipers b88ee700fc refactor: moved implementation to cpp file for polygon.shorterThan (CURA-738) 2016-04-22 16:16:15 +02:00
Tim Kuipers b43b98da25 bugfix: polygon.shorterThan didn't take last line segment into account (CURA-738) 2016-04-22 16:07:43 +02:00
Ghostkeeper ecdb4f7879 Codestyle: Space after control statement
Contributes to issue CURA-738.
2016-04-22 15:24:21 +02:00
Ghostkeeper 20ef9ce1c0 Codestyle: Space after control statement, always use brackets
Contributes to issue CURA-738.
2016-04-22 14:33:32 +02:00
Ghostkeeper aec58f7e00 Codestyle: Space around operators and after control statement
Contributes to issue CURA-738.
2016-04-22 14:06:01 +02:00
Tim Kuipers 7dca18fe6a removed debugging code 2016-04-21 14:35:39 +02:00
Tim Kuipers dc761c2f57 lil: removed commented code 2016-04-21 13:47:18 +02:00
Tim Kuipers 059c97b2cd refactor: moved implementation in Meshgroup.h to cpp file (CURA-520) 2016-04-21 13:46:01 +02:00
Tim Kuipers d14e05f318 refactor: jedi ==> griffin (CURA-520) 2016-04-21 13:31:39 +02:00
Tim Kuipers a533559918 fix: combing always went to closest point to origin, instead of crossing_1_in_or_mid (CURA-579) 2016-04-21 10:42:47 +02:00
Tim Kuipers 78ca299380 quickfix: set temperature during priming (CURA-520) 2016-04-20 17:13:26 +02:00
Tim Kuipers 1d581c0fec fix: only reset E-value after toolswitch (CURA-520)
Given that having an G92 E0 at the start of the first use of a toolhead is no problem in any printer, we can just reset the E-value every start of a toolhead
2016-04-20 14:53:06 +02:00
Tim Kuipers d0c58acfcf rebase fixes 2016-04-20 13:13:57 +02:00
Tim Kuipers 7b90354033 refactor: renaming local vars and rewrite of Remove all the tiny polygons 2016-04-20 13:10:30 +02:00
Tim Kuipers 5c4fdfdd0b refactor: renamed clipper polygon to path 2016-04-20 13:10:30 +02:00
Tim Kuipers c8051f5b37 refactor: renaming local vars 2016-04-20 13:10:30 +02:00
Tim Kuipers fa203bd976 refactor: some functions moved and extensive stitching moved to its own function 2016-04-20 13:10:30 +02:00
Tim Kuipers 4d2e544be0 refactor: renamed clipper polygon to path 2016-04-20 13:10:30 +02:00
Tim Kuipers bd27011107 bugfix: lil) 2016-04-20 13:08:04 +02:00
Tim Kuipers fb3c99ebe0 changed stitching poly decision 2016-04-20 13:08:03 +02:00
Tim Kuipers 2a8a86aac4 refactor: moved first stitching out of slicer 2016-04-20 13:08:03 +02:00
Tim Kuipers 4fa497ee8c bugfix: slicer didn't connect anything 2016-04-20 13:08:03 +02:00
Tim Kuipers 76eaeeb196 refactored first part of slicer: connect segments 2016-04-20 13:08:03 +02:00
Tim Kuipers 9cebeb770a Merge branch 'feature_combing_refactor' 2016-04-20 10:35:35 +02:00
Tim Kuipers a0200f1548 Merge branch 'feature_combing_refactor' 2016-04-20 10:32:46 +02:00
Tim Kuipers 83164fe1e7 fix: don't recalculate line distance in the engine (CURA-1317) 2016-04-19 17:30:43 +02:00
Tim Kuipers f9f162383b removed old test stls and gcode files 2016-04-19 16:41:59 +02:00
Tim Kuipers 403f7515b8 fix: forgot ProgressStageEstimator.h (CURA-873) 2016-04-18 17:38:38 +02:00
Tim Kuipers a0aa69f8b0 fix: forgot ConicalOverhang.h (CURA-1412) 2016-04-18 17:34:57 +02:00
Tim Kuipers 969ed87600 refactor: moved ProgressStageEstimator implementation to cpp file (CURA-873) 2016-04-18 17:30:22 +02:00
Tim Kuipers a2dccb118c Merge branch 'feature_progress_refactor_folder_refactor' 2016-04-18 17:23:38 +02:00
Tim Kuipers 64e5c5b8bf Merge branch 'feature_progress_refactor' 2016-04-18 17:22:46 +02:00
Tim Kuipers 8bb2a6ba7f refactor: moved progress files into separate folder (CURA-873) 2016-04-18 17:21:53 +02:00
Tim Kuipers da38e958ac Merge branch 'feature_rework_fffPolygonProcessor_per_mesh' 2016-04-18 17:02:49 +02:00
Tim Kuipers 081a46118c refactor: merged writeRetraction and writeRetraction_extruderSwitch (CURA-1431) 2016-04-18 15:45:00 +02:00
Tim Kuipers bd006e676b feat: zHop during extruder switch (CURA-1431) 2016-04-18 15:28:26 +02:00
Tim Kuipers afc40e1c70 refactor: moved extruder switch member values into normal RetractionConfig (CURA-1431) 2016-04-18 15:27:26 +02:00
Tim Kuipers cc6583b214 fix: writeRetraction did early exit sometimes when going from normal retracted to extruder switch retracted (CURA-1431) 2016-04-18 15:25:26 +02:00
Tim Kuipers 55fbd2ba54 refactor: extruder_attr[current_extruder] ==> extr_attr (CURA-1431) 2016-04-18 14:55:02 +02:00
Tim Kuipers 916d26417f fix: unretraction speeds were wrong when going from exdtruder switch retraction state to normal retraction state (CURA-1431) 2016-04-18 14:54:11 +02:00
Tim Kuipers 258a7e6f37 fix: let LayerplanBuffer decide the starting temperature (CURA-520)
That way flow dependent temperature decides on the starting temperature when using the command sucket
2016-04-18 13:39:43 +02:00
Tim Kuipers d5f13616c2 refactor: moved meshgroup_number to FffProcessor (CURA-520) 2016-04-18 11:44:57 +02:00
Tim Kuipers 54c7f942c4 fix: no more temp commands at start for Jedi gcode (CURA-520) 2016-04-18 11:07:57 +02:00
Tim Kuipers f63d78357b feat: conical ocerhang (CURA-1412) 2016-04-15 20:05:27 +02:00
Tim Kuipers bd565ab000 fix: don't zero extruder value after toolchange (CURA-959) 2016-04-14 18:09:29 +02:00
Tim Kuipers fc24ce974d feat: jedi prime gcode commands (CURA-520)
priming is now perfored by moving to a location, perform the prime gcode, retract, switch extruder, same for other extruder
2016-04-14 15:50:23 +02:00
Tim Kuipers 7a7c824b0d refactor: moved preSetup implementation to cpp file (CURA-520)| 2016-04-14 14:24:14 +02:00
Tim Kuipers a4227db5b1 fix: also set initial temps when doing wireprinting (CURA-520) 2016-04-14 14:21:58 +02:00
Tim Kuipers 7fdc77c74c Merge branch 'master' of https://github.com/Ultimaker/CuraEngine 2016-04-14 14:10:09 +02:00
Tim Kuipers 508b1b2933 machine extruder trains now can't be an array anymore (CURA-494) 2016-04-14 14:09:58 +02:00
Tim Kuipers 387ef30ca1 machine extruder trains now can't be an array anymore (CURA-494) 2016-04-14 13:21:00 +02:00
Tim Kuipers 1b6df75591 fix: jedi header (CURA-520) 2016-04-14 11:26:02 +02:00
Tim Kuipers 53ccadbf91 feat: const preserving getExtruderTrain function (CURA-520) 2016-04-14 11:23:05 +02:00
Tim Kuipers 612f6cac3d fix: extruder trains didn't get properly initialized when one-at-a-time printing with command line slicing 2016-04-14 11:16:45 +02:00
Tim Kuipers 166601492b fix: always prepend bogus header to fool firmware into accepting the print (CURA-520)
this was done so that Jedi gcode also always includes a header
it also means that UMO gcode always gets a header, which is ok, as it is ignored by that firmware
2016-04-13 16:13:43 +02:00
Ghostkeeper e0de929c5b Codestyle: Spaces around operators
Contributes to issue CURA-494.
2016-04-13 14:54:07 +02:00
Tim Kuipers 7ac4738435 feat: JEDI gcode flavor (CURA-520) 2016-04-13 13:07:11 +02:00
Tim Kuipers 4c547b9a66 fix const problem in BucketGrid2D (CURA-893) 2016-04-12 17:09:06 +02:00
Tim Kuipers 7ca184fb78 fix merge conflicts (CURA-893) 2016-04-12 16:53:00 +02:00
Tim Kuipers 080663a653 moved polygonUtilsTest (CURA-893) 2016-04-12 16:51:55 +02:00
Tim Kuipers cc54c8be08 Merge branch 'feature_skin_and_dual_combing' into feature_skin_and_dual_combing_merge 2016-04-12 16:49:38 +02:00
Tim Kuipers c19f35ce13 fix: writeRetraction didn't unretract if already retracted more (CURA-959) 2016-04-12 15:25:06 +02:00
Tim Kuipers 983720cfc0 fix: G92 E0 wasn't performed after the nozzle switch (CURA-959) 2016-04-12 15:24:16 +02:00
Tim Kuipers cad745f0b5 fix: infill_overlap ==> infill_overlap_mm (CURA-786) 2016-04-11 19:06:55 +02:00
Tim Kuipers 2a10954df2 lil fix: __cxx11::string ==> string 2016-04-09 01:55:11 +02:00
Tim Kuipers 7eded0ba3c Merge branch 'bugfix_support_z_xy_fight' 2016-04-08 14:39:13 +02:00
Tim Kuipers ca963d5da0 Merge branch 'bugfix_getSetting_calls' 2016-04-08 14:12:51 +02:00
Tim Kuipers 7091650876 Merge branch '2.1' 2016-04-08 13:36:26 +02:00
Tim Kuipers 93485cd0df Merge branch '2.1' of https://github.com/Ultimaker/CuraEngine into 2.1 2016-04-06 17:09:16 +02:00
Tim Kuipers 2d3382874a fix: polygon smoothing removed vertices which were connected to a small as well as a large line segment (CURA-1361) 2016-04-06 17:09:05 +02:00
Tim Kuipers 1e78397e18 fix: support max layer was set after each object (CURA-1360) 2016-04-06 17:05:33 +02:00
Ghostkeeper 6bcdd94f7e Copy protocol file from front-end
This synchronises the whitespace and comments from the front-end. The typeids are not necessary any more.

Contributes to issue CURA-1210.
2016-04-05 17:14:09 +02:00
Ghostkeeper accd28db64 Update documentation of sendLayerData
Contributes to issue CURA-1210.
2016-04-05 17:13:57 +02:00
Ghostkeeper 1c0f4c42d9 Remove superfluous set to nullptr
Shared pointers are already set to nullptr by default.

Contributes to issue CURA-1210.
2016-04-05 17:13:47 +02:00
Ghostkeeper 5da1632d9f Remove sliced object lists from protocol
Each layer is now sent individually, instead of grouped by object and grouping those objects in a sliced object list. The list was sometimes too large to send in one message. The objects weren't used by the front-end anyway.

Contributes to issue CURA-1210.
2016-04-05 17:13:37 +02:00
Ghostkeeper cbf1152f56 Remove object ID from layer
Turns out that it is not needed in the front-end either any more. If we need it in the future, we'll add it again.

Contributes to issue CURA-1210.
2016-04-05 17:13:22 +02:00
Ghostkeeper 2273c5aefe Alter protocol to no longer group sliced objects
They will be sent with one message per layer from now on.

Contributes to issue CURA-1210.
2016-04-05 17:13:09 +02:00
Tim Kuipers 991adf19a1 Merge branch 'master' of https://github.com/Ultimaker/CuraEngine 2016-04-05 11:49:07 +02:00
Tim Kuipers 9a4e1b52ed fix: always zero E value before AND after nozzle switch (CURA-959) 2016-04-05 10:53:25 +02:00
Ghostkeeper 98d2786dd0 Merge branch '2.1'
Conflicts:
	src/gcodeExport.h
	src/gcodePlanner.cpp
	src/utils/LinearAlg2D.cpp
2016-04-04 19:03:33 +02:00
Tim Kuipers 46c793e73d fix: lil string vs c_str bug (CURA-1231) 2016-04-04 14:15:14 +02:00
Tim Kuipers fd4969887b refactor: replaced all gcode output \n by new_line (CURA-1231) 2016-04-04 14:13:32 +02:00
Tim Kuipers 6620a050a5 feat: new_line string used for BFB machines (CURA-1231) 2016-04-04 14:13:10 +02:00
Tim Kuipers 6325197fce feat/refactor: moved file header generation to gcodeExport and introduced the NOZZLE_SIZE header comment (CURA-1231) 2016-04-04 14:03:38 +02:00
Tim Kuipers f828d44365 Merge branch 'feature_better_time_estimates' into 2.1 2016-04-04 12:14:19 +02:00
Tim Kuipers 5072995a66 documentation (CURA-537) 2016-04-04 12:06:28 +02:00
Tim Kuipers a8ab0c12aa code style: space after keyword 2016-03-30 17:44:36 +02:00
Tim Kuipers 09c989a019 code style: spaces around operators 2016-03-30 17:17:12 +02:00
Tim Kuipers 29564a23e0 refactor: introduced mm, mm3, E value conversion functions instead of inline is_volumetric checks (CURA-1293) 2016-03-30 12:35:11 +02:00
Tim Kuipers 1fdda3319f fix: volumetric time estimation was bugged (CURA-1293) 2016-03-30 12:24:27 +02:00
sean041 be113eceb4 Fix typo. downSkinCount -> upSkinCount (CURA-1299)
This typo causes flaky crash when downSkinCount < upSkinCount and ignore small z gaps is disabled.
2016-03-30 10:24:58 +02:00
Tim Kuipers 0b3b8ea33b Merge pull request #323 from sean041/patch-1
Fix typo. downSkinCount -> upSkinCount (CURA-1299)

this caused a crash when Ignore small z gaps was disabled and bottom was smaller than top thickness
2016-03-30 10:22:29 +02:00
Tim Kuipers 0c42ff9bfa fix: inner (2nd) wall was refered to even if it wasn't generated (CURA-1294) 2016-03-29 15:18:47 +02:00
sean041 a5bd599ec7 Fix typo. downSkinCount -> upSkinCount
This typo causes flaky crash when downSkinCount < upSkinCount.
2016-03-26 08:07:36 +08:00
Ghostkeeper 7548c41d7b Simplify test case
This test case now reduces to the normal test cases since there is only one option again. We can re-use the function that was made for normal test cases then.

Contributes to issue CURA-579.
2016-03-25 16:41:08 +01:00
Tim Kuipers cd033ef6ab doc: autobrief for first line (CURA-537) 2016-03-24 17:50:12 +01:00
Tim Kuipers e909af9abd documentation for fffProcessor (CURA-537) 2016-03-24 17:34:02 +01:00
Tim Kuipers dd5fbf14e4 document FffGcodeWriter (CURA-537) 2016-03-24 16:59:09 +01:00
Tim Kuipers 168e041c42 Merge branch '2.1' of https://github.com/Ultimaker/CuraEngine into 2.1 2016-03-24 15:58:16 +01:00
Ghostkeeper 670ae6dd8c Spaces around minus operator
Conforming to code style.

Contributes to issue CURA-863.
2016-03-24 15:58:11 +01:00
Tim Kuipers 20adfa751f doc+refactor: fan speed calc more clear (CURA-863) 2016-03-24 15:57:54 +01:00
Tim Kuipers bf8776b112 optimization: removed superluous recalculation of line direction in LineOrderOptimizer (CURA-1170) 2016-03-23 16:25:10 +01:00
Tim Kuipers 1d0f3f519a fix syntax mistake (CURA-1170) 2016-03-23 16:25:01 +01:00
Tim Kuipers 07fef8668c calculate incoming_perpundicular_normal in end stage of line order optimizer (CURA-1170) 2016-03-23 16:24:51 +01:00
Tim Kuipers 1c06fc49fc refactor: factor out getAngleScore from line order optimizer (CURA-1170) 2016-03-23 16:24:39 +01:00
Tim Kuipers beb9422d9b refactor: clear up pathOrderOptimizer for lines (CURA-1170) 2016-03-23 16:24:27 +01:00
Tim Kuipers a8359b9a68 refactor: small optimization of line order optimizer dot score (CURA-1170) 2016-03-23 16:24:17 +01:00
Tim Kuipers 5ccfe2d1aa refactor: clear up pathOrderOptimizer for lines (CURA-1170) 2016-03-23 16:24:07 +01:00
Tim Kuipers 74577759b4 refactor: expand complicated code in pathOrderOptimizer (CURA-1170) 2016-03-23 16:23:54 +01:00
Tim Kuipers 45eb026777 refactor: rewrite line order optimizer dot score stuff (CURA-1170) 2016-03-23 16:23:42 +01:00
Tim Kuipers aabb07fd81 refactor: simple renaming of incoming_perpendicular_normal (CURA-1170)
Conflicts:
	src/pathOrderOptimizer.cpp
2016-03-23 16:23:21 +01:00
Ghostkeeper 6377ec63e1 Add edge-case tests for getAngleLeft
These test what happens when two or more points are equal. There is nothing about this in the function specification, so it allows any output, but at least it shouldn't give like a divide by zero error.

Contributes to issue CURA-1170.
2016-03-23 16:14:11 +01:00
Tim Kuipers eab2d8e667 fix: improved dot-score for preferring the z-seam on inside corners (CURA-1170) 2016-03-23 16:13:58 +01:00
Tim Kuipers 8d41003c67 feat: linearAlg2D::getAngleLeft CMAKE (CURA-1170) 2016-03-23 16:13:48 +01:00
Tim Kuipers ecfae4d75c feat: linearAlg2D::getAngleLeft (CURA-1170) 2016-03-23 16:13:37 +01:00
Tim Kuipers a2208f6b69 fix: pathOrderOptimizer was bugged (CURA-1170)
polyStart indices used wrongly
2016-03-23 16:13:26 +01:00
Tim Kuipers bacacb01dc refactor: more cleanup of pathOrderOptimizer (CURA-1170) 2016-03-23 16:13:15 +01:00
Tim Kuipers 94c9399f2c refactor: intpoint::crossZ ==> turn90CCW (CURA-1170) 2016-03-23 16:13:03 +01:00
Tim Kuipers 168dc3c12b refactor: more cleanup of pathOrderOptimizer (CURA-1170) 2016-03-23 16:12:53 +01:00
Tim Kuipers 235af65b00 refactor: code cleanup helper functions of PathOrderOptimizer (CURA-1170) 2016-03-23 16:12:43 +01:00
Tim Kuipers f3f3be74cc refactor: code cleanup of PathOrderOptimizer - lines (CURA-1170) 2016-03-23 16:12:32 +01:00
Tim Kuipers dca0bc80b5 fix: PathOrderOptimizar::polyStart had wrong indexing (CURA-1170) 2016-03-23 16:12:18 +01:00
Tim Kuipers c0e57622d0 cleanup: more clarification of pathOrderOptimizer for polygons code (CURA-1170) 2016-03-23 16:12:04 +01:00
Tim Kuipers b7a8fbe798 cleanup: pathOrderOptimizer got cleaned up (CURA-1170) 2016-03-23 16:11:49 +01:00
Ghostkeeper 0985b97c54 Merge branch 'master' of https://github.com/Ultimaker/CuraEngine 2016-03-23 16:08:58 +01:00
Tim Kuipers 06521eef8b lil 2016-03-23 12:32:44 +01:00
Tim Kuipers 47a6f0dc36 fix: made it possible to include warning and error functions in the graph; changed the way you should call the tool 2016-03-23 11:50:39 +01:00
Tim Kuipers 4353980e78 refactor: made code more explicit: after smoothing speed (towards bottom layer speed) the speeds are set to their iconic speeds once and for all (CURA-1248) 2016-03-22 17:20:38 +01:00
Tim Kuipers 18ae9cf41d bugfix: alternate extra wall had skin overlapping with inner wall (CURA-1233)
To see if there was infill above, we looked at the innermost wall instead of the wall with index [wall line count]
2016-03-22 13:42:32 +01:00
Tim Kuipers 04edf35331 bugfix: bottom layer speed influenced all layers (CURA-1248)
smoothSpeed never got called for the final speed
2016-03-22 13:21:03 +01:00
Tim Kuipers ce4d34adb2 unit test fix: moveInside(polys, points, dist) may leave inside points as they are (CURA-579) 2016-03-21 17:51:38 +01:00
Tim Kuipers d42be2a22c removed old unused code 2016-03-21 17:29:22 +01:00
Tim Kuipers dbcbcae2e3 codestyle: closestHere ==> closest_here (CURA-893) 2016-03-21 17:26:04 +01:00
Tim Kuipers ff9cb24d99 refactor: auto ==> ClipperLib::Path (CURA-893) 2016-03-21 17:23:19 +01:00
Tim Kuipers b8ff36651e fix: tests failed due to changed GcodePlanner constructor (CURA-893)
combing changed from boolean to an enum
boolean is_inside_mesh was added
2016-03-21 17:16:24 +01:00
Tim Kuipers 98a78e1844 Merge branch 'master' of https://github.com/Ultimaker/CuraEngine 2016-03-21 12:30:52 +01:00
Tim Kuipers 37c8ad3061 lil (CURA-1217) 2016-03-21 12:28:56 +01:00
Tim Kuipers d2187fedbc optimization: removed superluous recalculation of line direction in LineOrderOptimizer (CURA-1170) 2016-03-21 12:17:20 +01:00
Tim Kuipers 5b0a50456f fix syntax mistake (CURA-1170) 2016-03-21 11:55:01 +01:00
Tim Kuipers 66f4b51a3e calculate incoming_perpundicular_normal in end stage of line order optimizer (CURA-1170) 2016-03-21 11:53:33 +01:00
Tim Kuipers 3ac6ee1b37 refactor: factor out getAngleScore from line order optimizer (CURA-1170) 2016-03-21 11:43:12 +01:00
Tim Kuipers 4d8b22a224 refactor: clear up pathOrderOptimizer for lines (CURA-1170) 2016-03-21 11:36:08 +01:00
Tim Kuipers 3a0143ff4c refactor: small optimization of line order optimizer dot score (CURA-1170) 2016-03-21 11:33:26 +01:00
Tim Kuipers c6a4945469 refactor: clear up pathOrderOptimizer for lines (CURA-1170) 2016-03-21 11:21:08 +01:00
Tim Kuipers abc6514b6d refactor: expand complicated code in pathOrderOptimizer (CURA-1170) 2016-03-21 11:05:01 +01:00
Tim Kuipers dc26358747 refactor: rewrite line order optimizer dot score stuff (CURA-1170) 2016-03-21 10:52:23 +01:00
Tim Kuipers 3485e5a4ad refactor: simple renaming of incoming_perpendicular_normal (CURA-1170) 2016-03-21 10:34:55 +01:00
Tim Kuipers bd47fd2c67 removed unused old commented code 2016-03-21 10:24:42 +01:00
Tim Kuipers d7d957d8f7 Removed unused code 2016-03-19 16:17:02 +01:00
Ghostkeeper bec8c235ea Add edge-case tests for getAngleLeft
These test what happens when two or more points are equal. There is nothing about this in the function specification, so it allows any output, but at least it shouldn't give like a divide by zero error.

Contributes to issue CURA-1170.
2016-03-18 14:12:51 +01:00
Ghostkeeper eb1bbd41b0 Codestyle: Spaces around binary operators
Contributes to issue 1170.
2016-03-18 13:07:28 +01:00
Tim Kuipers 49f2f21c08 feat: linearAlg2D::getAngleLeft (CURA-1170) 2016-03-17 17:40:53 +01:00
Tim Kuipers 9ed25b95ee fix: improved dot-score for preferring the z-seam on inside corners (CURA-1170) 2016-03-17 17:39:38 +01:00
Tim Kuipers c8b8abd4c6 feat: linearAlg2D::getAngleLeft CMAKE (CURA-1170) 2016-03-17 17:39:38 +01:00
Ghostkeeper 37c461fa86 Merge branch '2.1'
Conflicts:
	src/FffGcodeWriter.cpp
	src/inset.cpp
	src/pathOrderOptimizer.cpp
2016-03-17 15:43:03 +01:00
Tim Kuipers 7d9c8ee1b1 fix: pathOrderOptimizer was bugged (CURA-1170)
polyStart indices used wrongly
2016-03-17 09:45:28 +01:00
Tim Kuipers 5df73e0e30 refactor: more cleanup of pathOrderOptimizer (CURA-1170) 2016-03-16 16:59:40 +01:00
Tim Kuipers 5d8926e3e7 refactor: intpoint::crossZ ==> turn90CCW (CURA-1170) 2016-03-16 15:43:49 +01:00
Tim Kuipers 277c478e3b refactor: more cleanup of pathOrderOptimizer (CURA-1170) 2016-03-16 15:38:59 +01:00
Tim Kuipers 6f654241f7 refactor: code cleanup helper functions of PathOrderOptimizer (CURA-1170) 2016-03-16 15:17:17 +01:00
Tim Kuipers 62910c9d0a refactor: code cleanup of PathOrderOptimizer - lines (CURA-1170) 2016-03-16 15:13:36 +01:00
Tim Kuipers f92ee17577 fix: PathOrderOptimizar::polyStart had wrong indexing (CURA-1170) 2016-03-16 15:02:15 +01:00
Tim Kuipers dc3d94e0a8 cleanup: more clarification of pathOrderOptimizer for polygons code (CURA-1170) 2016-03-16 15:01:25 +01:00
Tim Kuipers 6c9db68573 cleanup: pathOrderOptimizer got cleaned up (CURA-1170) 2016-03-16 14:53:54 +01:00
Tim Kuipers fc046d5978 fixed visualization stuff for only doing parent-child or inheritance 2016-03-16 13:48:22 +01:00
Tim Kuipers 2bd8657050 vizualize dependence of child on parent via inheritance function as normal parent-child relation 2016-03-16 13:34:21 +01:00
Tim Kuipers 6718a8b2f3 fix: made engine not depend on support_z_distance, which is a parent setting value (CURA-1171) 2016-03-16 09:36:05 +01:00
Tim Kuipers 08c69ca589 child-parent arrow color overrides inheritance 2016-03-16 09:29:35 +01:00
Tim Kuipers a3d17d217a DSg 2016-03-15 18:23:11 +01:00
Tim Kuipers e47fcea2bf sdg 2016-03-15 18:21:11 +01:00
Tim Kuipers ad3903037c how to use this branch 2016-03-15 18:15:34 +01:00
Ghostkeeper f7cdd63f1d Codestyle: Whitespace around operators
Space around binary operators. No space around unary operators.

Contributes to issue CURA-1098.
2016-03-15 12:18:54 +01:00
Tim Kuipers 3400439f5d Merge branch 'master' of https://github.com/Ultimaker/CuraEngine 2016-03-15 10:18:07 +01:00
Tim Kuipers 5fbf9a8907 made outer wall offset a setting instead of being calculated from the difference between nozzle size and wall_line_width_0 (CURA-1098) 2016-03-15 10:00:01 +01:00
Ghostkeeper df6d2fc592 Codestyle: Whitespace around binary operators
Contributes to issue CURA-1097.
2016-03-14 16:50:10 +01:00
Ghostkeeper 08a5ec7dee Codestyle: Whitespace around binary operators
Contributes to issue CURA-1097.
2016-03-14 16:45:56 +01:00
Ghostkeeper 3de01763c1 Codestyle: Whitespace around binary operators.
Contributes to issue CURA-1097.
2016-03-14 16:41:34 +01:00
Tim Kuipers 7fc18c2057 made combing depend on inner wall line width instead of nozzle_size (CURA-1097) 2016-03-14 13:21:05 +01:00
Tim Kuipers c7bf1e087a made rafts' combing not depend on nozzle_size (CURA-1097) 2016-03-14 13:16:04 +01:00
Tim Kuipers bc7ee74d19 made combing depend on inner wall line width instead of nozzle_size (CURA-1097) 2016-03-14 11:02:32 +01:00
Tim Kuipers fc20a6661b made rafts' combing not depend on nozzle_size (CURA-1097) 2016-03-14 10:37:46 +01:00
Ghostkeeper cffd6ac860 Spaces around minus operator
Conforming to code style.

Contributes to issue CURA-863.
2016-03-10 12:13:26 +01:00
Tim Kuipers 81d521a58b quickfix: remove outer wall offset based on nozzle size (CURA-1097) 2016-03-10 09:56:18 +01:00
Ghostkeeper 205c4f8cc9 Add test for new filter function
Contributes to issue CURA-590.
2016-03-09 14:38:23 +01:00
Ghostkeeper c797163536 Add more tests for findNearestObject
Contributes to issue CURA-590.
2016-03-09 14:28:14 +01:00
Ghostkeeper d31acdb244 Add first test for findNearestObject
Contributes to issue CURA-590.
2016-03-09 14:07:55 +01:00
Ghostkeeper 810f689418 Add tests for a group of points on a line
Contributes to issue CURA-590.
2016-03-09 13:02:41 +01:00
Ghostkeeper 7270290fe3 Improve findNearbyObjects test template
It now allows for some points for which the answer (near or far) is indeterminate.

Contributes to issue CURA-590.
2016-03-09 12:28:39 +01:00
Ghostkeeper 37e3114311 Add two simple tests for BucketGrid2D::findNearbyObjects
Contributes to issue CURA-590.
2016-03-09 12:16:16 +01:00
Ghostkeeper c3ef64fe18 Add initial test case for BucketGrid2D::findNearbyObjects
This is just an initial test and the testing framework for this unit.

Contributes to issue CURA-590.
2016-03-09 12:09:03 +01:00
Ghostkeeper 5d592553a6 Add test directory for infill
To make it complete for future tests that might appear there.
2016-03-09 11:00:03 +01:00
Ghostkeeper 38fad10453 Move utils tests to subdirectory
This keeps the same directory structure in the tests directory as in the source directory, as is common.
2016-03-09 10:50:10 +01:00
Tim Kuipers c4eb1d9f27 bugfix: uninitialised infill (CURA-1084)
not always did the basic infill_area get initialised, notably when there was no infill, which should be an empty polygon instead of no polygon
2016-03-08 17:52:12 +01:00
Ghostkeeper 1c16c77d56 Add test cases for moveInside
One of the edge cases currently fails.

Contributes to issue CURA-579.
2016-03-08 17:28:09 +01:00
Tim Kuipers 883f0c7419 current setting inheritance structure 2016-03-07 13:50:51 +01:00
Tim Kuipers bc11121a2e feat: ouput json inheritance structure 2016-03-07 13:50:51 +01:00
Tim Kuipers 0dbf80587b Merge branch '2.1' 2016-03-07 09:50:02 +01:00
Tim Kuipers 32d1bb6d75 bugfix: one-at-a-time printing went to z height of last position planned on the previous object (CURA-988) 2016-03-02 13:55:46 +01:00
Tim Kuipers afdb552f63 bugfix: retraction limitation segfaulted when retraction count == 1, cause it handled retraction count as if it was [retraction count - 1] (CURA-977) 2016-03-01 13:18:53 +01:00
Tim Kuipers a400ba28f2 fix: supportOnByuildplateOnly didn't account for conical support (CURA-914) 2016-03-01 12:06:54 +01:00
Tim Kuipers d18843abe3 fix: all settings now implicitly retrieved from meshgroup instead of explicitly (CURA-927) 2016-02-29 13:58:15 +01:00
Tim Kuipers ea12d310b0 fix: all settings retrieved from meshgroup instead of globally (CURA-927) 2016-02-29 13:54:36 +01:00
Tim Kuipers b993e4aff1 fix: support_roof_height was retrieved globally and per mesh - now only per mesh (CURA-956) 2016-02-29 13:39:35 +01:00
Tim Kuipers e0a7818d9e fix: infill wipe distance also on skin (CURA-964) 2016-02-29 13:03:42 +01:00
Tim Kuipers 277b5dce75 fix: get infill sparse combine per mesh (CURA-949) 2016-02-29 12:21:11 +01:00
Tim Kuipers 462a6e8c16 bugfix: skin didn't overlap with walls (CURA-941) 2016-02-29 12:16:02 +01:00
Tim Kuipers 20701117fb fix: support line width retrieved from same settings base everywhere (globally) (CURA-956) 2016-02-29 11:29:40 +01:00
Tim Kuipers a40d48c1be fix: initial layer speed for support requested from extruder train (CURA-956) 2016-02-29 11:18:20 +01:00
Tim Kuipers d7e966ad83 Merge branch 'analog10-master' 2016-02-29 10:40:58 +01:00
Tim Kuipers 593dd03987 Merge branch 'master' of https://github.com/analog10/CuraEngine into analog10-master 2016-02-29 10:37:19 +01:00
Tim Kuipers 07203c9d91 lil: removed unused const-incorrect function 2016-02-29 09:25:31 +01:00
David Bender 59e6a075e8 made a few intpoint methods const 2016-02-26 11:37:57 -05:00
David Bender 3f348ab1ba more const correctness for MeshGroup 2016-02-26 11:34:05 -05:00
David Bender 44fedbae7a make fpoint and fmatrix methods const 2016-02-26 11:33:29 -05:00
David Bender 77a378ba1c const cleanups in the Mesh class 2016-02-26 11:24:57 -05:00
David Bender 4f408847fb make members of settingRegistry.h const 2016-02-26 11:20:27 -05:00
Tim Kuipers 8d941063c1 fix: get raft settings from extruder train settingsbase; get extruder_nr settings with getSettingAsIndex instead of getSettingAsCount (CURA-956) 2016-02-25 20:04:56 +01:00
Tim Kuipers 471d20ff75 fix: print temp at startingCode based on extrudertrain settingsbase & lil bugfix '->' ==> '.' (CURA-956) 2016-02-25 19:55:59 +01:00
Tim Kuipers b82d6f9aff fix: retrieve machine_nozzle_size from extruder (CURA-956) 2016-02-25 18:41:24 +01:00
Tim Kuipers 277e1581d0 fix: retrieve all layer_height and layer_height_0 settings from meshgroup or global settings (CURA-956) 2016-02-25 18:32:35 +01:00
Tim Kuipers d4b128e0f3 fix: retrieve all layer_height settings from meshgroup or global settings (CURA-956) 2016-02-25 18:30:40 +01:00
Tim Kuipers eec65df83e refactored SliceMeshStorage storage ==> mesh (CURA-956) 2016-02-25 18:15:08 +01:00
Tim Kuipers 78e1c3114d refactor: introduce getSettingInMillimeters (CURA-956) 2016-02-25 18:07:39 +01:00
Tim Kuipers 5941d2252c fix: get infill sparse combine per mesh (CURA-949) 2016-02-25 10:21:44 +01:00
Tim Kuipers 6897a87584 fix: infill direction switch every two layers when infill_sparse_thickness is 2 layers and pattern is lines (CURA-943) 2016-02-25 09:49:51 +01:00
David Bender cc2bb36fb4 getSetting functions should be const 2016-02-24 11:01:57 -05:00
David Bender 0ea387a6f0 min/max functions should be const 2016-02-24 11:01:16 -05:00
Tim Kuipers 14a01a6253 fix: supportOnByuildplateOnly didn't account for conical support (CURA-914) 2016-02-24 16:07:32 +01:00
Tim Kuipers c20d35e293 fix: used adress comparison on ListPolygons instead of in depth comparison (CURA-934) 2016-02-23 16:23:09 +01:00
Tim Kuipers 9e56841cd2 fix: explicitly deleted polygon comparison, cause it is inefficient, and you most likely need to compare either the memory adress or need to account for the fact that two different polygons might have a different starting point (CURA-934) 2016-02-23 16:21:30 +01:00
Tim Kuipers c39e43c161 bugfix: combing shortcuts to end of comb move (CURA-893) 2016-02-23 15:38:33 +01:00
Tim Kuipers 421a6d4095 removed line from wrong cherry-pick (CURA-894) 2016-02-23 15:38:23 +01:00
Tim Kuipers 8497e46542 bugfix: moveInside always moved in the positive direction for the corner case (CURA-579) 2016-02-23 15:33:04 +01:00
Tim Kuipers 6510ebbd92 Merge branch '2.1' of https://github.com/Ultimaker/CuraEngine into 2.1 2016-02-22 17:27:06 +01:00
Tim Kuipers c1b4a5398b bugfix: small zgaps no-heuristic bugfixes (CURA-921)
It didn't create the right amount of top and bottom layers and didn't work correctly on the topmost and bottom most layers.
2016-02-22 17:26:57 +01:00
Arjen Hiemstra 11c4b9339a Store layer messages in a hash map to speed up lookups for layers 2016-02-22 17:23:17 +01:00
Tim Kuipers 75efbac68e fix: cone angle sign inverted: more sensible fix (CURA-869) 2016-02-22 17:08:04 +01:00
Tim Kuipers cd199dc43e fix: cone angle sign inverted (CURA-869) 2016-02-22 16:50:27 +01:00
Tim Kuipers e85eec54ec bugfix: combing shortcuts to end of comb move (CURA-893) 2016-02-22 15:57:29 +01:00
Tim Kuipers dcc4d956b2 feat: limit inside boundary to infill (CURA-694) 2016-02-22 15:35:12 +01:00
Tim Kuipers 91249dd012 refactor: infill_area ==> infill_area_per_combine; introduced infill_area for the whole infill area (CURA-694) 2016-02-22 15:34:39 +01:00
Tim Kuipers 4de1f1abdf removed old unused function (CURA-694) 2016-02-22 15:32:48 +01:00
Tim Kuipers 59abad0197 feat: refactor combing from bool into enum; introduced noskin (CURA-694) 2016-02-22 15:31:54 +01:00
Tim Kuipers 0dc7e326c9 refactor: made combPath.throughAir a property of all combPaths (CURA-893) 2016-02-22 11:27:56 +01:00
Tim Kuipers 3271bde77e lil 2016-02-19 16:13:03 +01:00
Tim Kuipers 7b71426839 refactor: const correctness loosely related to combing (CURA-893) 2016-02-19 15:30:29 +01:00
Tim Kuipers 27e3df2fbc fix: one combing calc changed avoid_other_parts for the next (CURA-893) 2016-02-19 15:06:50 +01:00
Tim Kuipers 2e915039e6 fix: is_inside info is retained after layer switch (CURA-893) 2016-02-19 14:38:37 +01:00
Tim Kuipers 8262ff3ac6 refactor/fix: call setIsInside only in addMeshLayerToGcode (CURA-893) 2016-02-19 12:19:57 +01:00
Tim Kuipers 5cc0eb24ef optimization: faster moveOutside - if possible (CURA-893) 2016-02-19 10:59:31 +01:00
Tim Kuipers dad74e1cd6 fix: crossing_2_in_or_mid was based on itself instead of closest to crossing_1 (CURA-893) 2016-02-18 18:33:05 +01:00
Tim Kuipers a878a7f091 fix: setIsInside bugs (CURA-893) 2016-02-18 18:27:48 +01:00
Tim Kuipers 53a543c548 lil 2016-02-18 17:26:15 +01:00
Tim Kuipers 0366b9df71 feat: skip crossing computation when boundary to boundary is already closer than twice the avoid distance (CURA-893) 2016-02-18 17:23:51 +01:00
Tim Kuipers 9c1f74fff1 fix: moveInside registered wrongly whether the point was already on the correct side of the boudary (CURA-893) 2016-02-18 16:49:52 +01:00
Tim Kuipers 1e0d416a5b lil fix: wrong move outside distance for crossings for combing (CURA-893) 2016-02-18 16:46:39 +01:00
Tim Kuipers 4612c69ae3 feat: moveInside utility function; directly calls moveInside (CURA-893) 2016-02-18 15:57:17 +01:00
Tim Kuipers 916e0b221d fix: larger admitted crossing dist for combing (CURA-893) 2016-02-18 15:51:16 +01:00
Tim Kuipers a05d31456d feat: also use dist from start to crossing when evaluating which crossing is the best (CURA-893) 2016-02-18 13:28:06 +01:00
Tim Kuipers 8d82b8b943 bugfix: lil mistake in combing second crossing (CURA-893) 2016-02-18 13:16:18 +01:00
Tim Kuipers 948c9b7054 refactor & fix: made findBestCrossing return ClosestPolygonPoints themselves which makes it easy to move inside/outisde with the offset_dist_to_get_from_on_the_polygon_to_outside (CURA-893) 2016-02-18 12:09:49 +01:00
Tim Kuipers 28d13b4aa1 bugfix: crossing dists were based on wrong value (CURA-893) 2016-02-18 12:07:59 +01:00
Tim Kuipers 0b0f85f9ff bugfix: moveInside couldn't perform moving outside well (CURA-579) 2016-02-17 17:59:33 +01:00
Tim Kuipers ef55f2ea11 bugfix: combing crossing computation refered to wrong crossing (CURA-579) 2016-02-17 17:23:56 +01:00
Tim Kuipers 692180e185 bugfix: combing crossing computation refered to wrong crossing (CURA-579) 2016-02-17 17:23:27 +01:00
Tim Kuipers e25a681201 lil refactor (CURA-893) 2016-02-17 17:13:29 +01:00
Tim Kuipers dca1beeba2 feat: combing: better finding of good crossing between inside and outide (CURA-893) 2016-02-17 16:45:22 +01:00
Tim Kuipers d10fea3ee6 refactor: modified findClose(Polygon ,...) such that it returns pairs of points on the first and points on the second polygon (CURA-893) 2016-02-17 16:04:51 +01:00
Tim Kuipers 1e93ffd83b feat: made Comb have an optional bucketGrid mapping from locations to line segments in the outside boundary (computed when needed) (CURA-893) 2016-02-17 15:56:44 +01:00
Tim Kuipers d41b842b39 refactor: introduced some const correctness for BucketGrid (CURA-893) 2016-02-17 15:43:30 +01:00
Tim Kuipers 59c3047543 feat: introduced findClose for a whole polygon (CURA-893) 2016-02-17 15:41:15 +01:00
Tim Kuipers b53f147b14 doc: findClosest & createLocToLineGrid (CURA-893) 2016-02-17 14:59:11 +01:00
Tim Kuipers 1768072cec unittest: findClose (CURA-893) 2016-02-17 14:45:01 +01:00
Tim Kuipers b2b4847b85 bugfix: findClose: end point of line segment was inserted instead of start point (CURA-893) 2016-02-17 14:43:09 +01:00
Tim Kuipers 3a832ef492 feat: findClose based on BucketGrid (CURA-893) 2016-02-17 12:33:00 +01:00
Tim Kuipers 03749e98ea fix: BucketGrid.insert expected reference instead of an object (CURA-893) 2016-02-17 12:15:03 +01:00
Tim Kuipers 9e410e7007 lil include reorder 2016-02-17 12:01:23 +01:00
Tim Kuipers beab605308 lil (CURA-579) 2016-02-16 17:35:46 +01:00
Tim Kuipers 9de4b7e939 fix: combing now uses correctly offsetted points from in_between (CURA-579) 2016-02-16 17:31:15 +01:00
Tim Kuipers 0d7710ecd1 refactor: made combing make use of new moveInside (CURA-579) 2016-02-16 17:21:22 +01:00
Tim Kuipers fe7364c146 refactor: simplified moveInside code (CURA-579)
make use of getBoundaryPointWithOffset
2016-02-16 17:16:24 +01:00
Tim Kuipers 98b1fda1f1 lil (CURA-579) 2016-02-16 16:56:11 +01:00
Tim Kuipers 151bef23c9 tests: better moveInside tests for both moveInside functions (CURA-579) 2016-02-16 16:51:14 +01:00
Tim Kuipers b9a411df10 bugfix: moveInside always moved in the positive direction for the corner case (CURA-579) 2016-02-16 16:43:43 +01:00
Tim Kuipers 0f53a7a231 tests of PolygonUtils::moveInside(ClosestPolygonPoint) (CURA-579) 2016-02-16 16:42:11 +01:00
Tim Kuipers 57ac6aa926 refactor: make new moveInside function work on ClosestPolygonPoint (CURA-579) 2016-02-16 14:47:00 +01:00
Tim Kuipers 2ba03ff1dc fixes: improved moveInside function for when you already found the nearest polygon point (CURA-579) 2016-02-16 14:25:33 +01:00
Tim Kuipers f59ca9c33e fixes: moveInside function for when you already found the nearest polygon point (CURA-579) 2016-02-16 13:39:46 +01:00
Tim Kuipers 8fc6ee87ee introduced moveInside function for when you already found the nearest polygon point (CURA-579) 2016-02-16 13:32:24 +01:00
Tim Kuipers 48707d95f7 refactor: some more renaming in combing (CURA-579) 2016-02-16 10:52:53 +01:00
Tim Kuipers 7a1a900d78 refactor: better naming for stuff like inside_middle_from (CURA-579) 2016-02-15 18:07:24 +01:00
Tim Kuipers 38c8941b59 Revert "fix: no move outside if it's a detour (CURA-579)"
This reverts commit f28cf53651.
2016-02-15 17:18:34 +01:00
Tim Kuipers df47cf8b2d refactor: typo iddle ==> middle (CURA-579) 2016-02-15 17:13:51 +01:00
Tim Kuipers f28cf53651 fix: no move outside if it's a detour (CURA-579) 2016-02-15 17:03:33 +01:00
Tim Kuipers 9d063d885c refactor: code indentation for readability (CURA-579) 2016-02-15 16:57:07 +01:00
Tim Kuipers 3ec63017cc refactor: getBoundaryOutside now returns ref instead of pointer, cause it ensures the return is instantiated (CURA-579) 2016-02-15 16:55:28 +01:00
Tim Kuipers 26dfd02b26 refactor: separate inside_middle_from computation from inside_middle_to comp (CURA-579) 2016-02-15 16:42:53 +01:00
Tim Kuipers e177303c4b Merge branch '2.1' 2016-02-15 15:20:30 +01:00
Ghostkeeper 4c1c43649d Fix setting-crash test with function evaluation
The minimum value, maximum value, minimum warning value and maximum warning value of each setting is now evaluated as a function, preventing casting errors. Runtest.py runs without errors or even test failures again now.

Contributes to issue CURA-814.
2016-02-15 14:05:27 +01:00
Ghostkeeper 2372a78c9b Fix setting-crash test with function evaluation
The minimum value, maximum value, minimum warning value and maximum warning value of each setting is now evaluated as a function, preventing casting errors. Runtest.py runs without errors or even test failures again now.

Contributes to issue CURA-814.
2016-02-15 12:54:44 +01:00
Tim Kuipers d3f0a06ee0 lil TODO (CURA-833) 2016-02-12 12:09:37 +01:00
Ghostkeeper 4f524613fd Merge pull request #304 from soyersoyer/master
fix build warnings
2016-02-12 09:51:34 +01:00
Tim Kuipers f94c95dd97 bugfix: total layers got updated by infill mehses CURA-833 2016-02-11 21:21:23 +01:00
Tim Kuipers 07b7d84df2 bugfixes new progress system (CURA-873) 2016-02-11 20:56:35 +01:00
Tim Kuipers 97ee04c12b lil fixes better progress estimator structure (CURA-873) 2016-02-11 20:13:21 +01:00
Tim Kuipers 18c7c6bdb9 fix: more secure layer indexing in infill mehses (CURA-833) 2016-02-11 20:01:38 +01:00
Tim Kuipers e93770017f refactor+cleanup for infill mehses (CURA-833) 2016-02-11 19:56:15 +01:00
Tim Kuipers 60e1f30c60 lil optimization: less splitIntoParts in processInfillMesh (CURA-833) 2016-02-11 19:47:56 +01:00
Tim Kuipers d4844d08f2 lil refactor: processDerivedWallSkinInfill doesn't have argument TimeKeeper anymore (CURA-833) 2016-02-11 19:46:06 +01:00
Tim Kuipers 30df9853e4 bugfix: infill meshes had too much infill overlap (CURA-833) 2016-02-11 18:59:46 +01:00
Tim Kuipers 4ff00a8f73 first approximation infill meshes (CURA-833) 2016-02-11 18:25:45 +01:00
Tim Kuipers f5b7cadcb5 refactor progress for better progress during skin and insets (CURA-873) 2016-02-11 17:44:24 +01:00
Tim Kuipers 17ca8fce0a fix: progress fixed for fffPolygonProcessor refactor
CURA-872

there is no progress information during processing insets and skin of a single mesh
2016-02-11 16:44:48 +01:00
Tim Kuipers dbdbec44cc refactor: split up slices2polygons in functions which work on each mesh separately (CURA-872) 2016-02-11 16:21:50 +01:00
soyer a9fdad71b4 SettingConfig’s parent is unused 2016-02-11 16:17:55 +01:00
soyer 9fb6a217a4 use the std::abs, it has a proper overload for the long long 2016-02-11 16:15:35 +01:00
soyer c480c96066 this is a function declaration, and this is useless here 2016-02-11 16:13:38 +01:00
Tim Kuipers 1bcb38dcb6 Merge pull request #303 from soyersoyer/master
fix build in the without arcus case
2016-02-11 15:22:34 +01:00
soyer 0e7b164532 without arcus the code can’t send SlicingFinished message, so do nothing. 2016-02-11 12:11:34 +01:00
soyer 0f6bdfd36e the static CommandSocket::instance should be set without arcus too 2016-02-11 12:08:22 +01:00
Tim Kuipers 4d79ea3e9e doc+refactor: fan speed calc more clear (CURA-863) 2016-02-10 17:00:57 +01:00
Tim Kuipers 199fa070d6 feat: findNearestObject with extra conditions (CURA-590) 2016-02-10 11:43:46 +01:00
Tim Kuipers ef1dece5d2 fix: BucketGrid2D: disregard bucket-collision items in findNearbyObjects (CURA-590) 2016-02-10 11:19:19 +01:00
Tim Kuipers 87e42fd9bd fix: BucketGrid2D: enhancement of hashing protocols (CURA-590) 2016-02-10 11:12:54 +01:00
Tim Kuipers 8d0a75779d doc; refactor: BucketGrid2D (CURA-590)
introduced typedef CellIdx to make clear which Point variables are used to signify a cell index
2016-02-10 11:11:47 +01:00
Tim Kuipers e882b23d76 Merge branch '2.1' 2016-02-09 17:08:34 +01:00
Tim Kuipers 142f4d519f Merge branch 'bugfix_coasting_prime' into 2.1 2016-02-08 16:28:50 +01:00
Arjen Hiemstra 9ea43e7fc1 Move addListener call to before message registration
This makes it possible to receive debug information about message registration
2016-02-07 18:56:28 +01:00
Arjen Hiemstra 9b92de9b8b Add an Arcus::SocketListener subclass so we can log all errors and debug 2016-02-04 12:16:30 +01:00
Tim Kuipers 4361dbf8fb better print time output 2016-02-03 18:02:34 +01:00
Tim Kuipers 81ae074b86 Merge branch '2.1' 2016-02-03 17:45:04 +01:00
Ghostkeeper 6826581497 Fix compile error
That needs to be a C-string.
2016-02-02 13:08:25 +01:00
Jaime van Kessel 4fead4612b Merge branch 'new_arcus_api' of github.com:Ultimaker/CuraEngine into 2.1 2016-02-02 11:25:45 +01:00
Ghostkeeper f763edfb05 Send FinishedSlicing message later
The FinishedSlicing message was being sent after the mesh group is done slicing, but it should've been sent after all slicing is done (also other mesh groups and after sending the metadata). This indicates that the slicer is really really done.

Contributes to issue CURA-427.
2016-02-01 10:21:53 +01:00
Ghostkeeper 0e662d7d67 Register SlicingFinished message type
The message type of this message is 8 (as documented in the proto file).

Contributes to issue CURA-427.
2016-02-01 10:21:53 +01:00
Ghostkeeper 94d8c3ff32 Document protobuf message typeid
Contributes to issue CURA-427.
2016-02-01 10:21:53 +01:00
Arjen Hiemstra 8e91753afc Ignore ObjectList messages with no objects and Objects with no vertices 2016-01-28 18:17:24 +01:00
Tim Kuipers 3171bd4dcb fix: infill overlap in mm (CURA-786) 2016-01-28 16:30:07 +01:00
Tim Kuipers 199007fa76 Merge branch '2.1' 2016-01-28 15:07:26 +01:00
Tim Kuipers 203eb05d7c bugfix: support overlapping with model for xy_distance=0 (CURA-795) 2016-01-28 13:22:23 +01:00
Tim Kuipers 9e75f8c70c fix: z distance used at overhang instead of xy-distance (CURA-795)
factored computeBasicAndFullOverhang out of generateSupportAreas
keep overhang areas in a rolling deque so that they are available for the current layer and the layer supportZDistanceTop above
implemented some polygon magic to ensure that the distance of support to overhang areas is less than from non-overhang areas
2016-01-28 13:12:24 +01:00
Tim Kuipers 93b3d2e46e refactor: made some functions const in sliceDataStorage (CURA-795) 2016-01-28 13:03:49 +01:00
Arjen Hiemstra 21e59cc1e2 Update CommandSocket with the new Arcus API 2016-01-28 03:24:12 +01:00
Tim Kuipers f0f14b0be3 fix: prime too slow after coasting due to unset speed (CURA-796) 2016-01-27 17:40:04 +01:00
Tim Kuipers a82c00bead fix: prime too much after coasting (CURA-796) 2016-01-27 17:39:37 +01:00
Tim Kuipers 14b1c5333a fix: retraction was prevented for non-direct support to support moves which did avoid other parts (CURA-777)
most notably I introduced path[0] == lastPosition && path[1] == p to the condistion; rest is just restruction
2016-01-27 12:16:20 +01:00
Tim Kuipers bbe809dabc fix: sendPolygons in coasting had a lil bug (CURA-778)
sendPolygons was called for lines toward the starting point instead of the new point

also a line was sent for the coasted path, which is actually just a move path
2016-01-25 17:08:45 +01:00
Tim Kuipers ed581a92b2 fix: reintroduced infill_overlap for the right features (CURA-765) 2016-01-25 16:38:47 +01:00
Tim Kuipers 9b68305851 refactor: matrix ==> rotation_matrix (CURA-401) 2016-01-25 12:01:09 +01:00
Tim Kuipers 940d3a86bd refactor: moved some implementation comments and renamed 'uneven' to 'odd' (CURA-401) 2016-01-25 11:27:52 +01:00
Tim Kuipers 55047120d8 refactor: split ZigZagConnectorProcessor into separate files (CURA-401) 2016-01-25 11:05:58 +01:00
Tim Kuipers e50b00fd73 fix: introduced new socket msg SlicingFinished (CURA-427) 2016-01-22 10:57:27 +01:00
Tim Kuipers 7377f30fd0 lil (remove unused var) 2016-01-21 10:26:24 +01:00
Tim Kuipers c9245e0926 Merge branch '2.1' of https://github.com/Ultimaker/CuraEngine into 2.1 2016-01-20 14:55:28 +01:00
Tim Kuipers 7149b7dbf1 fix: infill was overlapping with wall with incorrect amount; skin was incorrect when using a single wall and the outer wall line width differs from the inner walls (CURA-729) 2016-01-20 14:37:13 +01:00
Ghostkeeper daa3927a99 Merge branch '2.1' of https://github.com/Ultimaker/CuraEngine into 2.1 2016-01-20 14:34:13 +01:00
Ghostkeeper 074d1125e6 Fix STL header size
This was actually causing errors with loading STL files.

Sort of contributes to issue CURA-605.
2016-01-20 14:33:52 +01:00
Tim Kuipers a92274678d Merge branch '2.1' of https://github.com/Ultimaker/CuraEngine into 2.1 2016-01-20 11:22:36 +01:00
Tim Kuipers 081393d7f0 fix: offset issues (CURA-401) 2016-01-20 11:22:10 +01:00
Tim Kuipers 30da3097d0 lil code convention refactor (CURA-401) 2016-01-19 17:33:46 +01:00
Tim Kuipers d830fc515b lil 2016-01-19 17:28:47 +01:00
Tim Kuipers 5f2d924771 refactor: let fill_angle and line_distance be retrieved from Infill members (CURA-401) 2016-01-19 17:23:01 +01:00
Tim Kuipers b1ab1cae5a refactor: renamed variables to lower_case (code convention) (CURA-401) 2016-01-19 17:19:49 +01:00
Tim Kuipers 1fb6b20d90 refactor: let in_outline and outlineOffset be retrieved from Infill members (CURA-401) 2016-01-19 17:14:29 +01:00
Tim Kuipers dfb4c98e35 doc: infill documentation (CURA-401) 2016-01-19 13:40:21 +01:00
Tim Kuipers e455d63ad2 refactor: made infill generation functions public and let them use Infill member variables; also a bugfix where a PointMatrix was requested but a double was given (CURA-401) 2016-01-19 13:07:45 +01:00
Tim Kuipers cb024c73b1 refactor: made infill generation functions non-static (CURA-401) 2016-01-19 12:45:59 +01:00
Tim Kuipers d2d25058cb more comments for infill generation (CURA-401) 2016-01-19 12:29:12 +01:00
Tim Kuipers e85362370b more comments for (zigzag) infill generation (CURA-401) 2016-01-19 12:24:18 +01:00
Tim Kuipers 00c6f5c092 refactor: extrusionWidth ==> infill_line_width (CURA-401) 2016-01-18 17:29:14 +01:00
Tim Kuipers 818c7da951 lil comments (CURA-401) 2016-01-18 17:28:58 +01:00
Tim Kuipers 41723c8b38 removed unused registerPolyStart (CURA-401) 2016-01-18 17:22:10 +01:00
Tim Kuipers c8d75dd913 refactor: cleaned up inheritance structure of ZigZagConnectorProcessor classes (CURA-401)
removed code duplication by introducing another class called ActualZigzagConnectorProcessor.

explained the inheritance structure in the base class description.

made some things protected instead of public.
2016-01-18 16:49:39 +01:00
Tim Kuipers faa60c408f doc: documentation cleanup and expansion (CURA-401) 2016-01-18 15:27:40 +01:00
Tim Kuipers 7e322bc57c refactor: correction of tabs and spaces only (CURA-401) 2016-01-18 14:55:07 +01:00
Tim Kuipers 888fc54660 refactor: made all global infill functions private static (CURA-401) 2016-01-18 14:53:33 +01:00
Tim Kuipers fd660fcc11 refactor: connect_zigzags ==> connected_zigzags (cura-401) 2016-01-18 14:18:56 +01:00
Tim Kuipers e8080422a4 refactor: generateLineInfill_alt ==> generateLinearBasedInfill (CURA-401) 2016-01-18 14:16:33 +01:00
Tim Kuipers 5fecf2cd17 removed all old unused generateLine/ZigZagInfill code (CURA-401) 2016-01-18 14:15:26 +01:00
Tim Kuipers b4bf17c6be refactor: let rotation_matrix bubble down from Infill class; introduce some appropriate consts (CURA-401) 2016-01-18 14:07:38 +01:00
Ghostkeeper fabd658b53 STL file binary vs. ASCII detection robust against whitespace
The ASCII file may contain whitespace at the start of the file. This causes the STL file to be flagged as binary (since it doesn't start with "solid"). This fix first skips all whitespace before trying to find "solid".

Contributes to issue CURA-605.
2016-01-17 04:42:48 +01:00
Ghostkeeper a2050de513 Binary STL load use file size instead of face count
To determine the amount of memory allocated and the amount of faces to try to load, use the size of the file rather than the reported face count in the file. The reported face count may be missing or corrupt, in which case the engine would crash. If that happens now, it might miss one face. It will also give a warning if the reported face count does not match.

Contributes to issue CURA-605.
2016-01-17 04:09:14 +01:00
Tim Kuipers 9bfb5b17e9 refactor: made ZigzagConnectedEndpieces and ZigzagDisconnectgedEndpieces inherit from virtual ZigzagEndpieces; fix: several bugfixes (CURA-401)
notably the disconnected endpieces now disconnects all endpieces instead of half
2016-01-15 17:37:03 +01:00
Tim Kuipers e93d39d6d5 fix: disconnected endpieces (zigzag); reordered some of the connected endpieces code (CURA-401) 2016-01-15 17:16:46 +01:00
Tim Kuipers 175a65415a fix: support zigzag connected endpieces bugfixes (CURA-401)
before, only half of the endpieces were drawn

some problems had slipped into the translation, such as the resetting after each polygon
2016-01-15 16:53:39 +01:00
Tim Kuipers 74986dd95c lil refactor: changed last_var to this_var at the moment it was set for conceptual clarity (CURA-401) 2016-01-15 16:49:55 +01:00
Tim Kuipers 55dd35ae5e refactor: logic simplifications; fix: reintroduce skipping of scanline if poly is simple (CURA-401)
rewrote some for-if combinations which could be made simpler

small polygons which only cover a single scanline which are printed in total don't need the scanline...
2016-01-15 15:39:25 +01:00
Tim Kuipers 8caf810642 refactor: code conventions etc for generate(Lines/Zigzag)Infill (CURA-401) 2016-01-15 15:23:41 +01:00
Tim Kuipers 76efc41407 refactor: merge of generate(Lines/ZigZag)Infill (CURA-401) 2016-01-15 14:50:24 +01:00
Tim Kuipers b0a0fe8f30 refactor: code conventions in generate infill paths (CURA-401) 2016-01-14 11:17:06 +01:00
Tim Kuipers 653b631ffd lil 2016-01-14 11:16:36 +01:00
Tim Kuipers b9a01ed031 bugfix: made MargeInfill.isConvertible not static, cause it needs the nozzle_size class member (CURA-581) 2016-01-13 12:10:37 +01:00
Tim Kuipers de9d3bb447 lil fix: MergeInfill.nozzle_size used instead of line_width (CURA-581)
MergeInfillLines already had a member nozzle_size, though still it had a line defining a local variable 'int nozzle_size = line_width; // TODO'

Also some minor code convention brackets...
2016-01-13 11:50:47 +01:00
Arjen Hiemstra 8f5a46f77d Ensure we use libc++ as stdlib on OSX 2016-01-06 16:56:04 +01:00
Tim Kuipers d0858bbdb6 merge of 2.1 2016-01-06 15:03:29 +01:00
Tim Kuipers c22793b5d7 Merge branch '2.1' of https://github.com/Ultimaker/CuraEngine into 2.1 2016-01-05 18:22:52 +01:00
Tim Kuipers 1e684f23a7 refactor: removed old sendPolygons functions (CURA-379) 2016-01-05 18:22:34 +01:00
Tim Kuipers 7d0025975b refactor: removed old sendPolygons functions (CURa-379) 2016-01-05 18:20:44 +01:00
Tim Kuipers 5c892b564b fix: send all polygons at end of slicing process instead of during (CURA-379) 2016-01-05 18:17:03 +01:00
Tim Kuipers d5327ec3f1 refactor: let all CommandSocket calls go throught CommandSocket.getInstance() (CURA-379) 2016-01-05 17:35:12 +01:00
Tim Kuipers c48104bc86 refactor: made CommandSocket a kind of singleton class (CURA-379) 2016-01-05 17:09:08 +01:00
Tim Kuipers f58f1daec3 refactor: commandSocket ==> command_socket (CURA-379) 2016-01-05 17:08:24 +01:00
Tim Kuipers 669bb523a3 bugfix: commandSocket depends on there being a NoneType (CURA-581) 2016-01-05 13:07:26 +01:00
Tim Kuipers fa74f672ac lil 2016-01-05 12:23:44 +01:00
Tim Kuipers e224d9c853 MergeInfillLines early abort if space filling type is not Lines (CURA-581) 2016-01-05 12:23:10 +01:00
Tim Kuipers 338d80a7a9 lil fix in test (CURA-581) 2016-01-05 12:20:46 +01:00
Tim Kuipers 87123dac31 introduction of GCOdePath.space_fill_type (Polygon,Line or PolyLine) (CURA-581) 2016-01-05 12:20:09 +01:00
Tim Kuipers 73de288f44 lil cleanup of unused commented out code (CURA-581) 2016-01-05 11:30:43 +01:00
Tim Kuipers 9f5b5f405d lil enhancements mergeInfillLines (CURA-581) 2016-01-05 11:27:06 +01:00
Tim Kuipers 2850b34227 fix: mergeInfillLines aborts if applied to a print feature other than infill or skin (CURA-581) 2016-01-05 11:23:51 +01:00
Tim Kuipers 072d320f1d refactor: FeatureType ==> PrintFeatureType (CURA-581) 2016-01-05 11:11:39 +01:00
Tim Kuipers 8e4b61d2a5 merge of 4c139d6441 (CURA-581) 2016-01-05 11:10:56 +01:00
Tim Kuipers ba4e26f801 bugfix: concentric infill overlapped with skin; extra offset for concentric infill moved inside infill.cpp (CURA-650) 2016-01-05 10:04:33 +01:00
Tim Kuipers cea0a0a98f bugfix: no draft shield or concentric infill sendPolygons (CURA-639) 2016-01-04 16:55:41 +01:00
Ghostkeeper 2b51a11739 Fix new command socket not propagating to LayerPlanBuffer
This caused the command socket in LayerPlanBuffer to remain null, thus never flushing the g-code until the very end, thus causing the front-end to interpret the entire g-code as one layer, thus causing the post processing plugin to inject g-code at the wrong places.

Contributes to issue CURA-443.
2015-12-31 11:22:37 +01:00
Tim Kuipers cc23d73532 refactor: FeatureType ==> PrintFeatureType (CURA-606) 2015-12-18 16:32:13 +01:00
Tim Kuipers 4c139d6441 refactor: PolygonType ==> FeatureType in PrintFeature.h (CURA-606) 2015-12-18 16:32:02 +01:00
Tim Kuipers 13a18549bf Merge branch '2.1' 2015-12-18 14:32:47 +01:00
Tim Kuipers d32443ca9b bugfixes: merge infill (CURA-581) 2015-12-18 14:25:07 +01:00
Tim Kuipers 792aa9e8e8 merge infill improvements (CURA-581) 2015-12-18 12:50:50 +01:00
Tim Kuipers a63abb4e88 merge infill improvements maybe (CURA-581) 2015-12-18 10:49:12 +01:00
Tim Kuipers 9f82f58f03 bugfix: moveInside called with max_dist instead of max_dist_squared (CURA-522) 2015-12-15 16:33:51 +01:00
Tim Kuipers bd2f66e2eb bugfix: child settings got duplicated in extruder trains... (CURA-494) 2015-12-14 15:29:26 +01:00
Tim Kuipers 267eb7aef0 bugfix: made engine work both both extruder trains being an array as it being an object (CURA-494) 2015-12-14 14:14:08 +01:00
Tim Kuipers df04467ab1 better doc (CURA-522) 2015-12-09 17:24:05 +01:00
Tim Kuipers bbd9412b5f bugfixes moveInside (CURA-522) 2015-12-09 17:23:50 +01:00
Tim Kuipers c476acd522 bugfix: moveInside distance was BS (CURA-522) 2015-12-09 17:22:50 +01:00
Tim Kuipers 278efdeb39 merge of cherry-pick of 6115bde (CURA-522) 2015-12-09 17:22:09 +01:00
Tim Kuipers bb8a9dacba removed Comb.moveInside and Comb.isInside and inlined the implementation (CURA-522)
Since comb_boundary_inside is now a field of gcodeplanner these utility functions were at an awkward place.

Conflicts:
	src/gcodePlanner.cpp
	src/gcodePlanner.h
2015-12-09 17:18:55 +01:00
Tim Kuipers 42420edeed merge of cherry-pick of 5c3727d (CURA-522) 2015-12-09 17:11:56 +01:00
Tim Kuipers be2e96f3fd getLayerSecondOrInnermostWalls functions (CURA-522) 2015-12-09 17:04:50 +01:00
Tim Kuipers 18adc0bbc9 merge of cherry-pick of c7ce43e (CURA-522) 2015-12-09 17:02:37 +01:00
Tim Kuipers e7824faefe merge of cherry-pick of c7ce43e (CURA-522) 2015-12-09 17:01:37 +01:00
Tim Kuipers 7199be1b4f merge of cherry-pick of d9e2b39 (CURA-522) 2015-12-09 16:54:13 +01:00
Tim Kuipers 8cd48bf5a2 settingsRegistry reorganized and made more robust; more stuff will override if possible; extruder trains can now be overridden (CURA-494) 2015-12-09 16:27:31 +01:00
Tim Kuipers a766455ec8 lil (CURA-494) 2015-12-09 16:24:47 +01:00
Tim Kuipers af08b57799 makefile now copies command_line_settings.json to binary dir (CURA-566) 2015-12-09 09:37:29 +01:00
Tim Kuipers dbecb29dc8 command line settings json (CURA-566) 2015-12-09 09:06:29 +01:00
Tim Kuipers 7df0a34464 lil bugfix settingsRegistry (CURA-566) 2015-12-09 09:05:39 +01:00
Tim Kuipers 925d50fc5d removed prime_tower_distance (was already unused) (CURA-566) 2015-12-09 09:05:11 +01:00
Tim Kuipers e3163586af Merge of branch 2.1 2015-12-08 16:24:53 +01:00
Tim Kuipers 727c863f1a optimization: handle socket object list after listening for messages (CURA-441) 2015-12-08 15:58:00 +01:00
Tim Kuipers d732c49dd7 bugfix: close socket before exiting the program (CURA-441) 2015-12-08 15:57:26 +01:00
Tim Kuipers 781fc5ed7b lil doc (CURA-524) 2015-12-08 14:48:19 +01:00
Tim Kuipers 7243cf6da4 renamed commandSocket.d to commandSocket.private_data (CURA-524) 2015-12-08 14:44:15 +01:00
Tim Kuipers 1cdcce4205 revert of 6224713998 (CURA-524) 2015-12-08 14:42:00 +01:00
Tim Kuipers acf381c008 bugfix: no vizualization of last layers trvel moves (CURA-524) 2015-12-08 14:29:44 +01:00
Tim Kuipers 4b7df9ddc0 lil refac + doc (CURA*524) 2015-12-08 14:28:52 +01:00
Tim Kuipers 7788a4a234 refactor: sendGCodeLayer ==> flushGcode (CURA-524) 2015-12-08 14:28:20 +01:00
Tim Kuipers 6224713998 renamed commandSocket.d to commandSocket.private_data (CURA-524) 2015-12-08 13:53:22 +01:00
Tim Kuipers db8b30d77a refactor: Min Volume Before Coasting doesn't include Coasting Volume anymore (CURA-528) 2015-12-08 13:32:31 +01:00
Tim Kuipers f58441a6ad refactor: added braces for checks of command_socket (CURA-499) 2015-12-08 13:16:03 +01:00
Tim Kuipers 050b9c88f2 bugfix: coasting volume more than min volume (CURA-528) 2015-12-07 18:03:40 +01:00
Ghostkeeper 8ac63fca6e Log a warning when trying to override nonexistent setting
If there's a problem in the front-end this should expose it.

Contributes to issue CURA-544.
2015-12-07 15:38:21 +01:00
Ghostkeeper 1383882bc5 Fixed segfault when provided with unknown settings
When an override of a setting is provided via the JSON the engine would crash. This ignores those settings.

Contributes to issue CURA-544.
2015-12-07 15:18:39 +01:00
Tim Kuipers 04b4b2c057 merge 2015-12-07 13:42:31 +01:00
Tim Kuipers 3a773d3c0f bugfix: layer plan buffer flush did flush water, but left the turd (CURA-463) 2015-12-07 12:39:25 +01:00
Tim Kuipers 734ddce3c8 lil (CURA-463) 2015-12-07 12:38:14 +01:00
Tim Kuipers 0b19936299 main didn't allow for next meshgroup to be processed (CURA-463) 2015-12-07 12:37:02 +01:00
Tim Kuipers 691d5de591 lil doc (CURA-499) 2015-12-04 17:04:45 +01:00
Tim Kuipers 490cef1a5c Merge branch '2.1' of https://github.com/Ultimaker/CuraEngine into 2.1 2015-12-04 16:57:00 +01:00
Tim Kuipers b777b55935 bugfix: output command line call (CURA-499) 2015-12-04 16:56:49 +01:00
Ghostkeeper 0f5fd8d6ca Merge branch 'master' of https://github.com/Ultimaker/CuraEngine 2015-12-04 16:47:16 +01:00
Ghostkeeper 645b06271d Remove support-specific test
Support is already tested somewhat in the default test model. This makes the testing a bit more efficient.

Contributes to issue CURA-349.
2015-12-04 16:46:59 +01:00
Ghostkeeper 0428c08152 Fix indenting
The main function of runtest.py was indented with tabs instead of spaces.
2015-12-04 15:58:53 +01:00
Tim Kuipers ef61337ef8 better doc (CURA-522) 2015-12-04 13:55:08 +01:00
Tim Kuipers 20c74dd22d lil bugfix CURA-486 (stiekum gekoppeld) 2015-12-03 18:47:12 +01:00
Tim Kuipers 188b190d21 inlined writePathWithCoasting (CURA-486) 2015-12-03 18:05:29 +01:00
Tim Kuipers 1cd128decd coasting collapsed: no more diff between move-coasting and retract-coasting (CURA-486) 2015-12-03 18:01:34 +01:00
Tim Kuipers 925247a54d bugfix: don't perform the retraction *during* coasting (CURA-486) 2015-12-03 18:00:34 +01:00
Tim Kuipers b8d5474811 merge 2015-12-03 14:57:13 +01:00
Ghostkeeper 4c60339695 Merge pull request #281 from Rhoban/master
Adding ENABLE_ARCUS option in CMakeLists

This allows compiling CuraEngine for command-line use only.
2015-12-03 11:01:57 +01:00
Gregwar e1a594ad3e ENABLE_ARCUS: Adding message(STATUS) line 2015-12-03 10:22:28 +01:00
Tim Kuipers 94d9a948ae bugfix: a zero length line has no 'beyond' (CURA-359) 2015-12-02 16:32:43 +01:00
Tim Kuipers 176bf2c887 bugfixes getDist2FromLineSegment (CURA-359) 2015-12-02 16:31:40 +01:00
Tim Kuipers 3cf208f8ed Merge branch '2.1' of https://github.com/Ultimaker/CuraEngine into 2.1 2015-12-02 14:54:32 +01:00
Tim Kuipers 08eec2ad1f bugfixes moveInside (CURA-522) 2015-12-02 14:54:21 +01:00
Tim Kuipers 41e012be5f bugfix: initialize comb_boundary_inside (CURA-522) 2015-12-02 14:53:39 +01:00
Tim Kuipers 8102f7a246 bugfix: moveInside distance was BS (CURA-522) 2015-12-02 14:32:18 +01:00
Tim Kuipers d527358a82 lil documentation cleanup (CURA-522) 2015-12-02 14:20:35 +01:00
Tim Kuipers 6115bdec2a bugfix: when combing was off, we didn't move inside before doing a retract (CURA-522) 2015-12-02 14:19:45 +01:00
Tim Kuipers 9f29cbd3fb removed Comb.moveInside and Comb.isInside and inlined the implementation (CURA-522)
Since comb_boundary_inside is now a field of gcodeplanner these utility functions were at an awkward place.
2015-12-02 14:18:46 +01:00
Tim Kuipers 5c3727d532 refactor: moved comb_boundary_inside outside of Comb to gcodePlanner (CURA-522) 2015-12-02 14:05:48 +01:00
Tim Kuipers 73152d84c7 getLayerSecondOrInnermostWalls functions (CURA-522) 2015-12-02 14:03:18 +01:00
Ghostkeeper 2b3f22872e Fix codestyle and superfluous commented code
Contributes to CURA-359.
2015-12-02 13:32:48 +01:00
Tim Kuipers c7ce43eb6c refactor: is_combing ==> is_inside (CURA-522) 2015-12-02 13:01:44 +01:00
Tim Kuipers d9e2b39baf bugfix: min travel dist was ignored (CURA-522) 2015-12-02 12:54:07 +01:00
Ghostkeeper fa03c3823f Merge branch '2.1'
Merging recent fixes to master, mostly to be able to get Jenkins to report the updated tests.
2015-12-02 12:15:39 +01:00
Ghostkeeper 34e86195e9 Correct getDist2FromLineSegmentZeroNearTest ground truth
20^2 is 400, not 40.

Contributes to CURA-359.
2015-12-02 12:13:24 +01:00
Ghostkeeper bad780c54b Add existing tests for zero-length lines to test suite
Think I forgot to add these two tests earlier.

Contributes to CURA-359.
2015-12-02 12:13:24 +01:00
Ghostkeeper 3ddbc1d53b Added test for large lines to point distance
This should test multiplication of rounding errors more properly.

Contributes to CURA-359.
2015-12-02 12:13:24 +01:00
Tim Kuipers 51757353b4 bugfix: skin orientation separate from infill orientation (CURA-363) 2015-12-02 11:47:08 +01:00
Tim Kuipers d931baa788 fix: reserve [extruder_count] extruder plans, so that it's quite unlikely for the vector to get resized (CURA-298) 2015-12-01 18:04:14 +01:00
Tim Kuipers 2cf0d40775 fix: reserve [extruder_count] extruder plans, so that it's quite unlikely for the vector to get resized (CURA-298) 2015-12-01 17:23:16 +01:00
Tim Kuipers d20df39d5f Merge branch '2.1' 2015-12-01 16:31:58 +01:00
Tim Kuipers 57bc411bc6 refactor: speed_iconic ==> speed_base, speed ==> speed_current (CURA-496) 2015-12-01 16:31:34 +01:00
Gregwar 0c30d27892 Adding ENABLE_ARCUS option in CMakeLists 2015-12-01 16:27:14 +01:00
Tim Kuipers 0c9562b273 rename: support_extruder_nr ==> support_infill_extruder_nr 2015-12-01 16:07:04 +01:00
Tim Kuipers 321a9c11e0 bugfix: dynamically sized array initialized as if constant (CURA-499) 2015-12-01 15:03:21 +01:00
Tim Kuipers 389950ed90 fix: made all huge classes non-copyable (meshgroup and weaver needed some fixing) (CURA-298) 2015-12-01 14:23:55 +01:00
Tim Kuipers 61e5187267 ducomentation stuff (CURA-414) 2015-12-01 14:04:07 +01:00
Tim Kuipers 3859d58571 indent 2015-12-01 13:41:23 +01:00
Tim Kuipers 345c599062 bugfix: retraction_count_max ignored when < 0, retractions not occuring when ==0 (CURA-414) 2015-12-01 13:39:44 +01:00
Tim Kuipers 73625b949f bugfix: retraction_count_max was retrieved as if it was in MM instead of a count (CURA-414) 2015-12-01 13:22:59 +01:00
Tim Kuipers bf1cf334e6 bugfix: retraction_extrusion_distance_window also in MM for wireprinting (CURA-414) 2015-12-01 13:18:33 +01:00
Tim Kuipers 13ec686608 bugfix: triangles infill (and others) rotated every layer (CURA-363) 2015-12-01 13:14:05 +01:00
Tim Kuipers 742eedda06 Merge branch 'master' of https://github.com/Ultimaker/CuraEngine 2015-12-01 12:30:37 +01:00
Tim Kuipers bc6a139d1f lil optimization (CURA-480) 2015-12-01 10:59:13 +01:00
Tim Kuipers 9770e91961 bugfix: first extruder plan might be empty, so then it should be removed (CURA-480) 2015-12-01 10:57:58 +01:00
daid 9e3dfb5b12 Allow running of test with just the default settings. 2015-11-30 15:22:13 +01:00
Ghostkeeper 8b244c1738 Fix order of initialisation
Turns out this was important. When an actually filled mesh was given, this was giving errors.

Contributes to CURA-510.
2015-11-30 14:59:24 +01:00
Tim Kuipers c05c3ddaed bugfix: always use safest distance for combing when a single distance is used for inside combing (CURA-480) 2015-11-27 16:32:41 +01:00
Tim Kuipers 804c288353 storage.getExtrudersUsed (CURA-480) 2015-11-27 16:30:04 +01:00
Ghostkeeper 22c1ff4efe Properly define travel speed in GCodePlannerTests
It has to make travel moves, and if the travel move has speed 0 this messes up the estimates, so make it not 0.
2015-11-27 16:12:41 +01:00
Ghostkeeper 811be991c1 Define some lenience in time material estimates test
They are estimates, after all. The ground truth too is estimated.
2015-11-27 16:12:41 +01:00
Ghostkeeper 684da831b2 Properly set the retraction speed and distance
The test currently fails due to a floating point rounding error. I'll give it some lenience, especially since both the ground truth and the supposed output are estimates.
2015-11-27 16:12:41 +01:00
Ghostkeeper a9ff4a3826 Update naive time estimates retraction test
It now actually performs a retraction. The test fails at the moment. It seems the planner is not properly constructed yet.
2015-11-27 16:12:41 +01:00
Ghostkeeper 6d2ecc7811 Add "-" operator for TimeMaterialEstimates
This allows you to get the estimates of segments of the g-code, such as what I want to do when making unit tests.
2015-11-27 16:12:41 +01:00
Ghostkeeper e77ae7362b Use checked meshgroup in constructing SliceDataStorage
The rest of this constructor was still using the input meshgroup, which might be nullptr. Make it use the field, which was checked for being nullptr and initialised if it was nullptr.
2015-11-27 16:12:41 +01:00
Ghostkeeper 571d592136 Add a check for nullptr when creating SliceDataStorage
For this I moved the constructor properly to the cpp file. This prevents the constructor from having to be compiled a million times, and having to compile a million other files each time you modify this constructor, and prevents having to compile the FffProcessor header each time too. Also, since meshgroup must be defined before initializeRetractionConfigs and initializeSkirtConfigs, they are now in the body of the constructor to properly define the order.
2015-11-27 16:12:41 +01:00
Ghostkeeper 4d1ebb33e6 Add test for naive time estimates
It will set up a very basic g-code planner and let it estimate the time and material it needs. Currently it only tests with empty g-code, but I mean to add a test with retraction once this works. Currently the setup gives a segfault.

Contributes to issue CURA-415.
2015-11-27 16:12:41 +01:00
Tim Kuipers 995f9786a4 bugfix: no more temp commands when using single extrusion and UM2 and no auto temp (CURA-468) 2015-11-27 13:40:50 +01:00
Tim Kuipers 3467593aa2 Merge branch 'master' of https://github.com/Ultimaker/CuraEngine 2015-11-27 11:06:09 +01:00
Tim Kuipers ef4b8abaf5 bugfix: speed was always set to speed_layer_0 (CURA-496) 2015-11-27 11:05:59 +01:00
daid f460eeef57 Fix the CPackConfig file for both cross compiling and local compiling of packages. Final filename of the deb file was wrong. 2015-11-27 09:40:10 +01:00
Tim Kuipers 488f82ccbc bugfix: no prime tower sendPolygons called (CURA-326) 2015-11-26 19:42:19 +01:00
Tim Kuipers db3e9ac5e6 bugfix: do make infill and skin between INNER walls (fix of bug introduced in last commit) (CURA-481) 2015-11-26 18:29:52 +01:00
Tim Kuipers 8529924bc4 bugfix: no more infill or skin between OUTER walls (CURA-481) 2015-11-26 13:59:14 +01:00
Tim Kuipers 03ff861904 fix: no more bs check; it is never checked when the first Z position is obtained from the initial currentPosition, which is an approximation of where the nozzle starts 2015-11-25 16:58:29 +01:00
Tim Kuipers b3752a43b4 bugfix: gcodeExport got copiedgit diff solves temp commands missing issue (CURA-298) 2015-11-24 18:27:45 +01:00
Tim Kuipers 7e47664a51 bugfixes: uninitialized extruderMM3perMM used ==> replaced by gcodePath.isTravelPath; speed increased by extruderSpeedFactor instead of travelSpeedFactor (CURA-298) 2015-11-24 17:43:47 +01:00
Tim Kuipers 1b6b5cb843 removed commented out premature gcode writing (before planning) 2015-11-24 17:04:02 +01:00
Tim Kuipers 0d98c6eaef bugfix: remove first extruder plan temp warm up commands (since they are handled by the start gcode already) (CURA-468) 2015-11-24 16:43:06 +01:00
Tim Kuipers 518a528596 bugfix: remove first extruder plan temp commands (since they are handled by the start gcode already) (CURA-468) 2015-11-24 16:05:28 +01:00
Tim Kuipers c9ea663a1b enforce single slicing by commandSocket. 2015-11-20 15:57:51 +01:00
Tim Kuipers 0a7355d25c remainder of refactor split: getExtruderTrain => createExtruderTrain (CURA-465) 2015-11-20 11:34:22 +01:00
Tim Kuipers fc6cad48af CuraEngine settings conversion 2015-11-20 09:00:03 +01:00
Tim Kuipers d4c7abf7ef refactor: commandSocket: object_to_slice ==> mehgroup (CURA-465) 2015-11-19 13:59:18 +01:00
Tim Kuipers c04274401a bugfix: commandSocket: objects inherited from global settings instead of from the extruder train (CURA-465) 2015-11-19 13:57:00 +01:00
TotalRetribution fb2dac0f96 Cleaned up White space in processInsets 2015-11-18 13:26:33 +00:00
TotalRetribution e2e9cf8ea8 Merge remote-tracking branch 'origin/master' into reverse_inset_order 2015-11-18 11:51:18 +00:00
Tim Kuipers ee8dd68046 revert of polygon constructor change (667644eee4) (CURA-349) 2015-11-18 11:37:48 +01:00
Tim Kuipers afcacd00a7 bugfix: primeTower memory issues (officially unrelated to CURA-414) 2015-11-18 11:31:55 +01:00
Tim Kuipers a5b31de404 early out when meshgroup is empty (CURA-349) 2015-11-18 11:20:15 +01:00
Tim Kuipers c8f1922966 early out when meshgroup is empty (CURA-349) 2015-11-18 10:29:17 +01:00
Tim Kuipers ac24325715 relaxed tests of LinAlg2D (CURA-359) 2015-11-17 18:03:11 +01:00
Tim Kuipers 4807e13de6 lil (CURA-359) 2015-11-17 18:02:10 +01:00
Tim Kuipers b389b24d9b better cmake lists 2015-11-17 18:00:21 +01:00
Tim Kuipers 121d13b57e removed stray references to gcode instead of gcode_layer
and removed a stray fan command - why was it even there?! it should have been in finalize and/or processNextMeshgroupGcode
CURA-299
2015-11-17 17:08:02 +01:00
Tim Kuipers b1dc67be71 factored out maxObjectHeight from finalize (CURA-405) 2015-11-17 16:51:26 +01:00
Tim Kuipers 2584c7b38c removed move upward before end gcode insertion (CURA-405) 2015-11-17 16:39:26 +01:00
Tim Kuipers ac8b0e149a bugfix: retraction dist used as if it was volume (CURA-415) 2015-11-17 14:25:34 +01:00
Tim Kuipers 03141f505d refactor: extruderSwitchRetraction ==> extruder_switch_retraction_distance; prime_amount ==> prime_volume (CURA-415) 2015-11-17 14:24:51 +01:00
Tim Kuipers e18659669e refactor: retraction_amount ==> retraction_e_amount , to reflect that its unit is either mm or mm^3 (CURA-415) 2015-11-17 13:58:12 +01:00
Tim Kuipers 903f3b11d1 lil: mm3 ==> mm^3 in comments (CURA-415) 2015-11-17 13:55:55 +01:00
Tim Kuipers 51f27fd0ca bugfixes retraction_amount vs retraction_distance (CURA-415) 2015-11-17 13:52:08 +01:00
Tim Kuipers b7d1e53992 lil: doc: units of several speed variables (mm/s) (CURA-415) 2015-11-17 13:45:16 +01:00
Tim Kuipers 461a90a319 refactor: retractionPrimeSpeed ==> extruder_attr[e].last_retraction_prime_speed (CURA-414) 2015-11-17 13:22:35 +01:00
Tim Kuipers b19c6751c5 neglected prime amount in naive time estimate cause it is in a different unit 2015-11-17 13:13:06 +01:00
Tim Kuipers e2479e12b0 reffactor: retraction.amount ==> retraction.distance 2015-11-17 13:11:38 +01:00
Tim Kuipers c67f691237 bugfix naive time estimate (CURA-415) 2015-11-17 12:14:03 +01:00
Tim Kuipers 9c8e32f37b PR style fixes 2015-11-17 10:52:51 +01:00
Tim Kuipers 124b116b0c Merge pull request #266 from markwal/master
Omit start temp if already in starting gcode
2015-11-17 10:43:47 +01:00
Ghostkeeper 0b8fd8209c Initialise variable to shut up compiler warning
This variable is always initialised by LinearAlg2D::getDist2FromLineSegment before it is used. But the compiler can't detect that it is, because it noticed that the variable is not changed in some cases (namely if the pointer is null). So this just shuts up the compiler.
2015-11-16 15:39:00 +01:00
Mark Walker 1534ff0361 Add new settings to control temperature prepend
material_bed_temp_prepend - if true, prepend the bed temperature gcode
material_bed_temp_wait - if true, use the set and wait variant gcode
material_print_temp_prepend - if true, prepend the extruder temperature gcode
material_print_temp_wait - if true, also prepend the wait for temperature gcode
2015-11-16 02:26:02 -08:00
Ghostkeeper b6268d8dc9 Initialise variable to shut up compiler warning
This variable is always initialised by LinearAlg2D::getDist2FromLineSegment before it is used. But the compiler can't detect that it is, because it noticed that the variable is not changed in some cases (namely if the pointer is null). So this just shuts up the compiler.
2015-11-13 16:55:00 +01:00
Ghostkeeper 3413f3abaa Initialise variable in case a polygon is empty
If an empty polygon was passed here in the outline, firstBoundarySegmentEndsInEven would be uninitialised. This initialises it by default to true so that the if statement after the loop exhibits predictably correct behaviour.
2015-11-13 16:50:52 +01:00
Ghostkeeper cb5c69d064 Continue running wireframe script if zero layers to initialise fields
Some fields of Weaver were not properly initialised if the script was cut short. It now checks at several places where zero layers would be a problem and just continues as best as it can.

Contributes to issue CURA-349.
2015-11-13 16:45:04 +01:00
Ghostkeeper afa7c5a0c0 Properly initialise retraction settings in wireframe
The retraction settings were not initialised and this caused wireframe printing to access uninitialised memory. This initialises it properly by loading them from settings. At one place the rest of the settings were still hardcoded with the todo that it should be loaded from settings, but I left that as-is for now.

Contributes to issue CURA-349.
2015-11-13 16:43:05 +01:00
Ghostkeeper 7cbfd42b8f Initialised variable that could be uninitialised in if statement
This variable was possibly uninitialised by the time it is first used in an if statement. This causes undefined behaviour. This now initialises it to false, which is correct behaviour if the variable is not changed (zero outlines).
2015-11-13 13:24:42 +01:00
Ghostkeeper 515bf4592e Set CMake debug version message to status type
Makes it more coherent with other messages in CMake.
2015-11-13 13:12:59 +01:00
TotalRetribution 57ec92a645 Merge remote-tracking branch 'origin/master' into reverse_inset_order 2015-11-13 11:13:26 +00:00
Ghostkeeper 667644eee4 Properly initialise Polygons
The polygons vector of the Polygons class was in some cases not initialised while the size of the vector was requested, causing Valgrind to report a conditional jump depending on uninitialised memory.

Contributes to issue CURA-349.
2015-11-13 12:04:06 +01:00
Ghostkeeper 17e00733a4 Make flow temp graph parsing more robust
It should try to get as much information from the string as possible, regardless of whether the string is correctly formatted or not. At many places it used to iterate through the characters indefinitely until the next separator was reached. Now it stops at the end of string and returns the information it gathered up to then.

Contributes to issue CURA-349.
2015-11-13 11:36:24 +01:00
Tim Kuipers 5142f8c1ba Merge branch 'master' of https://github.com/Ultimaker/CuraEngine 2015-11-13 11:12:41 +01:00
Tim Kuipers 432abf11d5 allround print tests (CURA-426) 2015-11-13 11:12:23 +01:00
Arjen Hiemstra 77361417a4 Merge branch '15.10'
* 15.10:
  Add support for setting CuraEngine version from CMake
  Spelling fix
2015-11-13 11:06:20 +01:00
Ghostkeeper 83da6b2072 Fix maximum object height for wireframe if wireframe empty
It can't request the height of the heighest layer if there are no layers. If there are no layers, the height is now 0. Fixes the wireframe printing issue.

Contributes to issue CURA-349.
2015-11-13 10:18:20 +01:00
Ghostkeeper e567f8265a Wireframe don't crash if meshgroup is empty
If the mesh group is empty, the wireframe slicing crashed since it tried to access slicerList[0], which was filled with a slicer for each meshgroup.

Contributes to issue CURA-349.
2015-11-13 10:18:20 +01:00
Tim Kuipers c20b07fe0d lil:indent 2015-11-13 09:56:14 +01:00
Tim Kuipers 10815b4f93 bugfix: extruder start/end position didn't account for the extruder offset (CURA-351) 2015-11-13 09:55:53 +01:00
Arjen Hiemstra a119be9021 Add support for setting CuraEngine version from CMake 2015-11-12 14:53:59 +01:00
Tim Kuipers 002692fe18 Merge branch 'master' of https://github.com/Ultimaker/CuraEngine 2015-11-12 13:16:22 +01:00
Tim Kuipers 99e9054f54 renaming: isRetracted==>retraction_amount_current & retraction_offset_from_zero==>retraction_amount_e_start (CURA-414) 2015-11-12 13:15:28 +01:00
Tim Kuipers eedd4adee3 bugfixes: unset prime_amount and wrong currentExtrudedVolume computation (CURA-414) 2015-11-12 13:03:38 +01:00
Tim Kuipers e110b864ce introduced firmware_retract (CURA-414) 2015-11-12 12:02:04 +01:00
Tim Kuipers 1109f97ae6 refactor getCurrentExtrudedVolume to only owrk on current_extruder (CURA-414) 2015-11-12 12:01:38 +01:00
Tim Kuipers 469ab32b5c bugfix: isRetracted was used instead of prime_amount (CURA-414) 2015-11-12 11:17:18 +01:00
Tim Kuipers e1390582ed bugfixes extruded_volume_at_previous_n_retractions (CURA-414) 2015-11-12 10:56:24 +01:00
Tim Kuipers 6b1b11b47b refactored out writeMoveBFB: fixed indentation 2015-11-12 09:29:48 +01:00
Tim Kuipers 3526edd04a refactored out writeMoveBFB 2015-11-12 09:28:39 +01:00
Tim Kuipers a101be9d2f bugfix: register extruded volume before extruder switch (CURA-414) 2015-11-12 09:21:05 +01:00
Tim Kuipers 52aedafc13 bugfixes extrusion_amount_at_previous_n_retractions (CURA-414) 2015-11-12 08:52:25 +01:00
Tim Kuipers afd1e2659e refactor: getExtrusionAmountMM3 ==> getCurrentExtrudedVolume (CURA-414) 2015-11-12 08:51:38 +01:00
Tim Kuipers 93896a6960 refactored out getFilamentArea (CURA-414) 2015-11-11 17:34:54 +01:00
Tim Kuipers 954a396d96 bugfix: retraction extrusion window was interpreted in mm instead of in micron (CURA-414) 2015-11-11 17:31:33 +01:00
Tim Kuipers 610880737f refactor: extrusion_amount ==> current_e_value (no more implicit storing of retracted amount); last_coasted_amount_mm3 + retraction_config.primeAmount ==> extruder_attr[.].prime_amount; (CURA-414) 2015-11-11 16:49:01 +01:00
Tim Kuipers 36ed9904b5 refactor: made retraction prime amount have mm3 unit (CURA-415) 2015-11-11 16:37:32 +01:00
Tim Kuipers 996fc2cbc1 refactor: isRetracted now tracks how far it is actually retracted (CURA-414) 2015-11-11 15:20:16 +01:00
Tim Kuipers 7af12e5526 lil 2015-11-11 14:25:50 +01:00
Tim Kuipers 0323179b4a bugfix?: long retraction 'overwrites' short retraction (CURA-414) instead of doing a long+short retraction 2015-11-11 14:25:35 +01:00
Tim Kuipers 91956ad0e6 bugfix: zhop created Z position gcode commands on every move in a z hop (If I understand correctly) (CURA-414) 2015-11-11 14:23:30 +01:00
Tim Kuipers ff9dbf9a51 refactor: isRetracted per extruder (CURA-414) 2015-11-11 14:22:15 +01:00
Ghostkeeper bbff888e23 Fix license header
I don't know how I keep getting this wrong.
2015-11-11 13:41:16 +01:00
Ghostkeeper 4460b9a1d0 Fix license header
I don't know how I keep getting this wrong.
2015-11-11 13:39:34 +01:00
Ghostkeeper dd161ef770 Rename libCuraEngineLibrary to lib_CuraEngine
It can't be named libCuraEngine, sadly, since that produces a naming conflict with the CuraEngine executable target itself. This is a better compromise than it was initially.
2015-11-11 13:39:34 +01:00
Ghostkeeper 30050349fa Git ignore test output file
This should not be committed along.
2015-11-11 13:39:34 +01:00
Ghostkeeper bafcb804f4 Streamline building with unit tests
It is no longer necessary to build CuraEngine twice if building unit tests. It now simply builds all of CuraEngine (except main.cpp) as a library, then builds main.cpp as separate application and links the CuraEngine library to it. Then it does the same with the tests: Just build the test suite as application and link the already-built library to it.
2015-11-11 13:39:34 +01:00
Tim Kuipers a7320a2d14 bugfix: nozzle switch retraction prime speed was ignored 2015-11-11 12:59:03 +01:00
Tim Kuipers a7e72ea917 bugfix: overriding json document can now add new settings to existing category 2015-11-11 12:18:26 +01:00
Tim Kuipers 61c9cb5a07 debug out functions for settings registry 2015-11-11 12:17:54 +01:00
Tim Kuipers d029d7294f lil 2015-11-11 11:08:49 +01:00
Tim Kuipers 4c2aaed215 merge from 15.10 2015-11-10 13:10:14 +01:00
Ghostkeeper 68602df6ee Spelling fix
This would prevent the g-code flavour from being recognised in RepRap machines.
2015-11-09 13:52:40 +01:00
Tim Kuipers 017fb03391 failsafe: extruder train defaults to global settings if it is not specified 2015-11-06 17:30:37 +01:00
Tim Kuipers 92f5311aaf failsafe: extruder train defaults to global settings if it is not specified 2015-11-06 17:30:15 +01:00
Tim Kuipers 00abb3ab4c lil: removed debug code 2015-11-06 17:23:09 +01:00
Tim Kuipers 4f9f55ab06 lil: removed debug code 2015-11-06 17:22:45 +01:00
Tim Kuipers dfc91d811f merge of bugfix for combing 2015-11-06 17:12:58 +01:00
Tim Kuipers 2bfdb2d612 bugfix: outside combing was skipped sometimes 2015-11-06 17:10:31 +01:00
Tim Kuipers 026f82540f bugfix: outside combing was skipped sometimes 2015-11-06 16:53:33 +01:00
Tim Kuipers 835424121f bugfix: outside combing was skipped sometimes 2015-11-06 15:46:33 +01:00
Tim Kuipers d87072f761 Merge branch '15.10' of https://github.com/Ultimaker/CuraEngine into 15.10 2015-11-06 15:44:51 +01:00
Tim Kuipers f89a747836 bugfix: outside combing was skipped sometimes 2015-11-06 15:44:42 +01:00
Ghostkeeper 767803d2bf Fix more indenting
I think this is on me. I merged this code once.
2015-11-06 11:10:55 +01:00
Ghostkeeper a808e9e8ed Fix indenting
At one place there was an accidental extra four spaces. At another place the alignment of a comment was off since it was aligned to a comment above it which had moved to the left.
2015-11-06 11:10:55 +01:00
Tim Kuipers 087efefc16 bugfix: new speed wasn't set; fixes CURA-396 2015-11-06 10:42:59 +01:00
Tim Kuipers 09afe2264a bugfix: new speed wasn't set; fixes CURA-396 2015-11-06 10:40:49 +01:00
Tim Kuipers 6866925a05 bugfix: gcode flavor prepended for UM2 was incorrect 2015-11-05 21:00:55 +01:00
Tim Kuipers 5ede92fb1b bugfix: gcode flavor prepended for UM2 was incorrect 2015-11-05 21:00:29 +01:00
Ghostkeeper 321ef643a4 Use static cast instead of c-style cast
The static cast has more predictable behaviour across compilers.
2015-11-05 17:53:17 +01:00
Ghostkeeper c43c876cbc Offset PolyCrossings in combing after iteration of basicpath
The offset could sometimes make the basicpath loop get stuck.
2015-11-05 17:53:17 +01:00
Ghostkeeper 3d596f1765 Report error if SVG file couldn't be opened for writing
If for some reason the opening of the file failed, an error is given that indicates where the file was opened. It still continues writing because the nature of this class requires it to fail fast rather than continue silently, but it should be easier to debug now. If silent fail behaviour is desired for this class then we could decide on that later. It involves checking for if(out) at every write function.
2015-11-05 17:53:17 +01:00
Ghostkeeper ff747fa88f SVG filewriter to use const points
This way they can be directly filled in as points into a function call without making a variable for them and passing that variable by reference.
2015-11-05 17:53:17 +01:00
Tim Kuipers 950441493c Merge branch 'master' of https://github.com/Ultimaker/CuraEngine 2015-11-05 17:49:01 +01:00
Tim Kuipers 0c7cca6f17 feature: always show gcode flavor 2015-11-05 17:48:45 +01:00
Tim Kuipers 41a1db1e55 feature: always show gcode flavor 2015-11-05 17:48:21 +01:00
Ghostkeeper c058a2b12b Separate test per assert in getDist2FromLineSegmentAssert
Rather than failing at the first assert, there are now only 2 asserts in these test cases. Also it allows for some leniency of 10 microns error in the distance, which was the actual reason I did this.
2015-11-05 17:34:51 +01:00
Tim Kuipers adc8341e49 bugfix: walls were visualized when wall_line_count==0 2015-11-05 12:06:31 +01:00
Tim Kuipers 0717594a15 bugfix: walls were visualized when wall_line_count==0 2015-11-05 12:05:42 +01:00
Ghostkeeper d6ed95ed81 Merge branch 15.10
Conflicts:
	src/settingRegistry.cpp
	src/skin.cpp
2015-11-04 14:44:12 +01:00
Ghostkeeper c72b05463a Combing path-polygon intersection only offset along path
This is slightly more efficient to compute, though it allows for combing closer to the polygon than the specified combing distance if the edge approaches parallel with the desired combing path.

Contributes to issue CURA-286.
2015-11-04 14:04:50 +01:00
Ghostkeeper eb1acd02a2 Fixed combing offset bug
A point was being moved inside the polygon to obtain waypoints for combing through the inside of the polygon. Then it was being moved outside the polygon with a larger offset, but the second move used the inside point of the first move, causing the resulting offset to be a bit too small. This keeps a copy of the original waypoint before moving it inside, which it uses only for computing the outside waypoint.

Contributes to issue CURA-286.
2015-11-04 14:04:50 +01:00
Tim Kuipers 102b9f9c75 setting inheritance diagram 2015-11-04 13:25:51 +01:00
Tim Kuipers abb0b9a763 refactor: extruder plan insert Inserts code moved to ExtruderPlan 2015-11-04 12:39:00 +01:00
Tim Kuipers 63eda27a50 no more error when no extruder trains are present 2015-11-04 11:17:25 +01:00
Tim Kuipers 5b1eeecf76 fix for support roof triangles infill 2015-11-04 11:16:50 +01:00
Tim Kuipers 41ede0727b Merge branch '15.10' of https://github.com/Ultimaker/CuraEngine into 15.10 2015-11-04 11:02:32 +01:00
Ghostkeeper 7ffec2e617 Remove unnecessary parallel line collision detection
Now that a collision is also triggered when the line crosses an endpoint of another line, the detection of collisions when the two lines are parallel is no longer needed.

Contributes to issue CURA-286.
2015-11-03 17:40:46 +01:00
Ghostkeeper 57ebcf0163 combineInfillLayers to stop if combining 1 or 0 layers
Combining 1 layer has no effect. Combining 0 layers is invalid. Therefore, if this function is made to combine 1 or 0 layers, it doesn't combine anything, and immediately returns.
2015-11-03 16:48:23 +01:00
Tim Kuipers 71ae42a949 lil: error=>warning 2015-11-03 16:45:07 +01:00
Tim Kuipers 49a1ed7f3b fix for support roof triangles infill 2015-11-03 16:20:56 +01:00
Tim Kuipers 190b5b789b no more error when no extruder trains are present 2015-11-03 15:17:58 +01:00
Tim Kuipers ad29876617 Merge branch '15.10' of https://github.com/Ultimaker/CuraEngine into 15.10 2015-11-03 09:17:42 +01:00
Tim Kuipers 07481a548c bugfix: settings overrides weren't working
Conflicts:
	src/settingRegistry.cpp
2015-11-03 09:17:32 +01:00
Ghostkeeper a6be90d3b4 Link libraries to CuraEngineLibrary rather than tests
It's CuraEngineLibrary that uses these libraries, not the tests themselves. It's better to link it to CuraEngineLibrary itself rather than to the test executables.
2015-11-02 16:56:41 +01:00
Ghostkeeper 3231d75d94 Use static cast instead of c-style cast
The behaviour of this cast is better defined.

Contributes to issue CURA-285.
2015-11-02 16:48:53 +01:00
daid 5e4080e0bb Add clipper and Arcus libraries to link targets in an attempt to fix the build. 2015-11-02 16:17:16 +01:00
Ghostkeeper 6432215ad9 Merge branch '15.10' of http://github.com/Ultimaker/CuraEngine
Conflicts:
	CMakeLists.txt
	src/FffGcodeWriter.cpp
	src/FffPolygonGenerator.cpp
	src/comb.cpp
	src/gcodeExport.cpp
	src/gcodeExport.h
	src/gcodePlanner.cpp
	src/gcodePlanner.h
	src/skin.cpp
	src/utils/SVG.h
2015-11-02 16:00:52 +01:00
Ghostkeeper 3a60d0cb01 Merge branch '15.10' of http://github.com/Ultimaker/CuraEngine
Conflicts:
	CMakeLists.txt
	src/FffGcodeWriter.cpp
	src/FffPolygonGenerator.cpp
	src/comb.cpp
	src/gcodeExport.cpp
	src/gcodeExport.h
	src/gcodePlanner.cpp
	src/gcodePlanner.h
	src/skin.cpp
	src/utils/SVG.h
2015-11-02 16:00:06 +01:00
Ghostkeeper 7d70768178 Tell CppUnit to output XML
The standard XmlOutputter seems to output JUnit-style XML.
2015-11-02 15:08:28 +01:00
Ghostkeeper 9c201e3396 Remove old try for return code
Directly returning the boolean didn't work.
2015-11-02 14:50:57 +01:00
Ghostkeeper f00c091ed1 Add actual tests for getDist2FromLineSegmentTest
It tests various types of line segments with points in various places. The tests are currently already failing...
2015-11-02 14:37:03 +01:00
Ghostkeeper 4574e0917e getDist2FromLineSegment pass by const reference
This allows for calling the function with constexpr types.
2015-11-02 14:32:57 +01:00
Ghostkeeper 4ae1f5e6bf Succeeded CppUnit integration
If you add -DBUILD_TESTS=true to CMake, it will add a test target for each test file. These can be executed separately as executable file, or they can be ran all at once with 'make test'.
2015-11-02 13:17:11 +01:00
Ghostkeeper ae02a91a5d Fix license
Yeah I've done that more often... Sorry.
2015-11-02 09:26:13 +01:00
Ghostkeeper 0781a8f4ef Initial setup of CppUnit in CMake
I've setup a basic test but it doesn't actually do anything.
2015-10-30 17:41:48 +01:00
Ghostkeeper f1902d88bf Merge branch 'master' of https://github.com/Ultimaker/CuraEngine 2015-10-30 17:08:45 +01:00
Ghostkeeper 4cc5c35564 Fix string casting
This script couldn't run because it couldn't convert the ints to strings. It shouldn't convert the ints to strings. It should convert the strings to ints (or floats).
2015-10-30 17:08:18 +01:00
Tim Kuipers f124a7e528 bugfix: settings overrides weren't working 2015-10-30 16:05:24 +01:00
Tim Kuipers 1cd8e1c500 refactor: moved LayerPlanBuffer implementation to cpp file 2015-10-30 15:31:24 +01:00
Tim Kuipers 6dc89bbe7f Merge branch 'master' of https://github.com/Ultimaker/CuraEngine 2015-10-30 13:37:54 +01:00
Tim Kuipers 16250c54c9 large refactor/bugfix: moved GcodePathConfig initialization to start of FffGcodeWriter.writeGcode(.) and moved setting of layer-dependent config settings inside GcodePlanner.writeGcode(.) 2015-10-30 13:32:49 +01:00
Ghostkeeper c6e201e307 Don't combine infill layers if infill is empty
If the infill density is 0 and it has to combine layers, it would try to access layers below the first layer that don't exist. Instead it will now not combine at all, saving some processing power too.

Contributes to issue Cura-285.
2015-10-30 12:34:31 +01:00
Ghostkeeper c5be07212e Use standard namespace for isinf
This one is in the standard namespace. Otherwise it won't compile on stricter compilers. Contributes to #2.
2015-10-30 11:42:04 +01:00
Tim Kuipers 7035e91ac6 refactor: split raft_config into raft_base_config, raft_interface_config, raft_surface_config 2015-10-29 15:45:14 +01:00
Tim Kuipers 4f972da7ae moved layer_height from GcodePathconfig to GcodePlanner 2015-10-29 15:29:17 +01:00
Ghostkeeper 47718a1ba4 Merge branch 'master' of http://github.com/Ultimaker/CuraEngine 2015-10-29 15:02:31 +01:00
Ghostkeeper 87db7232a1 Added a test case that would generate support
It requires different kinds of support: Support to buildplate, support not to buildplate, supporting edges and supporting faces.
2015-10-29 14:58:33 +01:00
daid b9f9c12d6c Merge branch 'master' of github.com:Ultimaker/CuraEngine 2015-10-29 14:40:16 +01:00
daid 046fa3ba8e Few changes after review by Ruben. Also adds some documentation, but not everything yet. 2015-10-29 14:40:05 +01:00
Tim Kuipers db039033ce lil raft fan speed bug 2015-10-29 11:47:32 +01:00
Tim Kuipers c0fa1b4a1a lil bugfix: no more redundant raft layer comments 2015-10-29 11:41:15 +01:00
Tim Kuipers 1d073600e4 Merge branch '15.10' of https://github.com/Ultimaker/CuraEngine into 15.10 2015-10-29 11:36:59 +01:00
Tim Kuipers 8f6cb82421 merge of raft bugfixes 2015-10-29 11:29:43 +01:00
Tim Kuipers a455913165 lil 2015-10-28 17:03:19 +01:00
Tim Kuipers 9b0e4be570 bugfixes print z when raft is present 2015-10-28 17:00:25 +01:00
Ghostkeeper 1023102e3a Log an error when layer height is not positive
In addition to returning false, sliceModel now also logs an error when the layer height is invalid.
2015-10-28 16:38:27 +01:00
Ghostkeeper 0ac334c849 Log an error when slicing failed
In the command socket, when slicing failed, it would just ignore the failure and continue. This is fine, but let's at least log an error when that happens.
2015-10-28 16:34:59 +01:00
Ghostkeeper 696e0132f4 Break when layer height is 0
After discussing this with several colleagues, this seems to be the desired behaviour.
2015-10-28 16:19:06 +01:00
Tim Kuipers f9a0e39a6a Merge branch 'master' of https://github.com/Ultimaker/CuraEngine 2015-10-28 15:22:08 +01:00
Tim Kuipers ff9e7f11ae optimization:infill layers arent combined when combine count=1 2015-10-28 15:21:44 +01:00
Ghostkeeper fb284397c2 Only assert for insane g-code values in debug mode
A preprocessor definition is added if CMAKE_BUILD_TYPE == DEBUG. So for release builds, set CMAKE_BUILD_TYPE properly to RELEASE and CuraEngine will no longer stop at the assertion.
2015-10-28 15:17:33 +01:00
daid f5e2c5a070 Handle the new string type setting in the test script. (for which I am wondering if this was introduced with agreement in the team...) 2015-10-28 13:47:15 +01:00
Ghostkeeper 85cfd422ba Remove infill_sparse_combine setting
In discussion, we deemed infill_sparse_thickness more clear to the user and infill_sparse_combine superfluous, since it is really an intermediary value used by the engine to round the thickness up. So now it is actually computed in the engine. Accompanying this commit will be a commit to Cura to remove the setting from the .json file.
2015-10-28 13:10:16 +01:00
Ghostkeeper c5334e355e Re-do minimum combine_infill_layers check
This was accidentally removed in the merge...
2015-10-28 12:49:39 +01:00
Tim Kuipers 086c38ac0b Merge branch 'master' of https://github.com/Ultimaker/CuraEngine 2015-10-28 12:45:37 +01:00
Tim Kuipers 4cb64bab67 Merge conflict resolve of feature_temp_compensation_gcodePlanner 2015-10-28 12:42:57 +01:00
daid 87eaa97f21 Return used commands on failure. 2015-10-28 10:47:22 +01:00
daid 59fc004f09 Did not report failure count from default test, causing the rest of the tests not to run. 2015-10-28 09:44:49 +01:00
daid 5dbfab6ffb Small fix in test script timestamp generator. 2015-10-28 09:36:19 +01:00
daid 5494ce12a5 Update test script to include the base name of the model filename, not the full path. And reduce the amount of random tests when previous tests are failing. 2015-10-28 09:35:13 +01:00
Tim Kuipers 1ed1de147a refactor: renamed heatup time settings: inverted unit: s/*C => *C/s 2015-10-27 16:15:18 +01:00
Tim Kuipers 1c0a616ec7 refactor: flow_temp_graph => material_flow_temp_graph 2015-10-27 15:36:49 +01:00
Tim Kuipers 82a4bff953 use material_flow_dependent_temperature to turn off flow based temp 2015-10-27 15:24:58 +01:00
Tim Kuipers f7bbda7599 new temp settings 2015-10-27 14:10:56 +01:00
Tim Kuipers 273f1f46f3 LayerPLanBuffer documentation 2015-10-27 13:31:45 +01:00
Tim Kuipers e81abe405d lil vector.reserve optimization 2015-10-27 12:29:08 +01:00
daid d0dd97ab04 Handle engine timeouts. 2015-10-27 12:27:39 +01:00
Tim Kuipers d0e6f5c07e Preheat documentation 2015-10-27 12:16:23 +01:00
Tim Kuipers f4eb33e14e made heatup and cool down temps depend on whether we are printing 2015-10-27 12:15:52 +01:00
daid 3d3ddc238f Forgot to actually supply the setting to the engine. 2015-10-27 12:15:44 +01:00
daid 704edd25af Merge branch 'master' of github.com:Ultimaker/CuraEngine 2015-10-27 12:09:53 +01:00
daid e33560beb6 Update test script to use the json file to run tests on settings. 2015-10-27 12:09:40 +01:00
Nicanor Romero Venier 71e486d007 Accepts 'help' as a known command 2015-10-27 10:25:17 +01:00
Tim Kuipers 4ca66b6916 Merge pull request #270 from nicanor-romero/master
Accepts 'help' as a known command
2015-10-27 10:23:28 +01:00
Nicanor Romero Venier 7e6c4661b9 Accepts 'help' as a known command 2015-10-27 09:49:12 +01:00
daid f96eaddf6c Removed code convention file, is moved to Ultimaker/meta as general code convention file for all projects. 2015-10-27 09:27:27 +01:00
Ghostkeeper eb2ae0d699 Correctly handle case of no layers
If there are no layers, the engine used to crash with an assertion error. Instead, it now returns an empty slice, which is correct behaviour. Fixes issue CURA-323.
2015-10-26 12:11:27 +01:00
Ghostkeeper bcee6c7cc2 No negative initial layer thickness
If this setting is zero or negative, make it the minimum layer thickness: 1 micron. Also fixed a mistake in the comment of the similar check for the normal layer thickness setting.
2015-10-26 11:52:32 +01:00
Ghostkeeper 3a28f5d547 No negative layer thickness
If this setting is zero or negative, make it the minimum layer thickness: 1 micron.
2015-10-26 11:47:53 +01:00
Tim Kuipers 5c41425859 lil rename 2015-10-23 17:12:07 +02:00
Tim Kuipers 85959b0aa7 handle tmep inserts during MergeInfillLines 2015-10-23 16:34:02 +02:00
Tim Kuipers 6bd1d9fe8c bugfix: MergeInfillLines copied itself 2015-10-23 15:50:34 +02:00
Tim Kuipers 3e43df9e60 forceMinimalLayerTime: lil optimization 2015-10-23 12:41:21 +02:00
Ghostkeeper 4b11b5946e Remove infill_sparse_combine setting
In discussion, we deemed infill_sparse_thickness more clear to the user and infill_sparse_combine superfluous, since it is really an intermediary value used by the engine to round the thickness up. So now it is actually computed in the engine. Accompanying this commit will be a commit to Cura to remove the setting from the .json file.
2015-10-23 12:14:06 +02:00
Ghostkeeper d558e24b43 Re-do minimum combine_infill_layers check
This was accidentally removed in the merge...
2015-10-23 11:43:51 +02:00
Ghostkeeper 5d6f45a71d Merge branch 'master' of http://github.com/Ultimaker/CuraEngine
Changed files:
 * src/skin.cpp
2015-10-23 11:41:29 +02:00
Ghostkeeper d827cc0f92 Never combine 0 layers
Infill_combine_layers of 0 is an invalid value. So perform this sanity check to make sure that infill_combine_layers is always at least 1.
2015-10-23 11:25:06 +02:00
Tim Kuipers faa580ffe6 refactored TimeMaterialEstimates.travel_time into retracted_travel_time and unretracted 2015-10-22 17:50:10 +02:00
Tim Kuipers 16679d68d0 unindent refactor 2015-10-22 16:44:27 +02:00
Tim Kuipers 9983ebac7b bugfix: layer_plan.processFanSpeedAndMinimalLayerTime called twice on the same layer 2015-10-22 16:42:48 +02:00
Tim Kuipers ee8ef2bfa5 variable buffer size; better idle temp handing; refactored insertPreheatCommand into single and multiExtrusion; more... 2015-10-22 16:30:15 +02:00
Tim Kuipers 7646426f9d LayerPlanBuffer.cpp to move function bodies to 2015-10-22 16:26:45 +02:00
Ghostkeeper 263eb370e9 Handle edge case of parallel line intersection
If a line was parallel with an edge of the polygon, the line should be marked as intersecting that edge to properly register the scanline crossing. This handles that edge case for most cases by adding one intersection. In some cases it is plausible that two intersections should be registered. For those cases this procedure is still wrong, since it is computationally expensive to detect them.
2015-10-22 13:34:13 +02:00
Ghostkeeper c0d22dcf7b Move middle_from and middle_to inside as well
When combing needs additional waypoints (middle_from and middle_to), these waypoints weren't offset away from the edge towards the inside of the mesh. This caused all sorts of mistakes with edge cases. This prevents these edge cases.
2015-10-22 13:29:57 +02:00
Ghostkeeper 01d0a3b8d6 Add variant of writeAreas for point vector
Rather than having to supply a polygon, you can now supply a vector of points too. This helps if you want to visualise a custom polygon. Rather than having to clone a polygon some way, clear it and fill it with your own points, you now don't have to create a polygon container at all.
2015-10-22 11:29:59 +02:00
Ghostkeeper 1dd7313332 Fix moveInside corner cases
When the specified point is closest to a vertex of the polygon rather than an edge, the computed inward direction was wrong. I think this was a typo.
2015-10-22 11:15:59 +02:00
Ghostkeeper 7a7d1ebd77 Edge cases in moveInside
If we're moving points inside, points on the edge also have their direction of motion altered. This effectively means that the corner case happens more often.
2015-10-22 11:11:20 +02:00
Tim Kuipers 2976b1276c refactor: Insert ==> NozzleTempInsert 2015-10-22 11:01:19 +02:00
Tim Kuipers b84f41d9b0 bugfixes: waited for temp on wrong places; inserted preheat commands for each layer instead of jsut the last 2015-10-21 18:05:59 +02:00
Tim Kuipers f142df9176 bugfix: use correct extruder for which to preheat; included cool down inserts 2015-10-21 17:42:23 +02:00
Tim Kuipers 94f90419dd Merge branch 'master' of https://github.com/Ultimaker/CuraEngine 2015-10-21 17:00:13 +02:00
Tim Kuipers 90547bb69c bugfix: dual prime tower was broken (gave SEGFAULT on acces of config)
Conflicts:
	src/FffGcodeWriter.cpp
2015-10-21 16:59:59 +02:00
Tim Kuipers 3611d53222 bugfix: dual prime tower was broken (gave SEGFAULT on acces of config) 2015-10-21 16:56:00 +02:00
Tim Kuipers ab7ca73596 bugfixes for dual extrusion in LayerPlanBuffer 2015-10-21 16:35:18 +02:00
Tim Kuipers c42568c059 first working preheat inserts in gcode 2015-10-21 15:55:17 +02:00
Tim Kuipers 43eb784b6c cleanup old LayerPLanBuffer code and debug output 2015-10-21 13:35:45 +02:00
Tim Kuipers 68f1eb1fd2 better temp update starting time 2015-10-21 13:31:58 +02:00
Ghostkeeper 3dfb84b9a1 Added include(Point) for 2D bounding boxes too
This functionality already existed for 3D axis aligned bounding boxes. It makes it easier to construct a bounding box when no explicit polygon is available. To facilitate this, the bounding box is properly constructed with high minimum value too.
2015-10-21 12:28:03 +02:00
Ghostkeeper 80896e3f4d Fix order of parameter initialisation
This caused a compiler warning.
2015-10-21 12:16:49 +02:00
Tim Kuipers 6518e14e18 lil code convention braces 2015-10-21 12:05:47 +02:00
Tim Kuipers 4c95e43048 refactor: extrudeSpeedFactor (lil) made more verbose 2015-10-21 12:03:56 +02:00
Tim Kuipers 4c66b7fd01 lil 2015-10-21 11:46:50 +02:00
daid 97ebfe8b12 Remove RPM build. 2015-10-21 10:13:33 +02:00
Tim Kuipers 0cb8b64f70 rewrote LayerPlanBuffer.insertPreheatCommands 2015-10-20 18:12:27 +02:00
Tim Kuipers bfc2d458ae refactor: renamed TempFlowGraph to FlowTempGraph 2015-10-20 13:51:50 +02:00
Tim Kuipers 365de0578c refactor: renamed TempFlowGraph to FlowTempGraph 2015-10-20 13:50:09 +02:00
Tim Kuipers d9c30de796 lil 2015-10-20 13:46:50 +02:00
Ghostkeeper e8cb1028e4 Add check against divide by zero
If two consecutive points are exactly equal, a divide by zero would happen here. This check prevents the divide in that case and skips the second of the points then.
2015-10-20 13:34:32 +02:00
Tim Kuipers bc41b415c2 LayerPlanBuffer: insert temp commands at flush 2015-10-20 13:32:32 +02:00
Ghostkeeper d4adbb97bf Merge master of http://github.com/Ultimaker/CuraEngine
Changed files:
 * src/comb.cpp
 * src/comb.h
2015-10-19 17:06:09 +02:00
Ghostkeeper c8488f6d37 Add writeDashedLine
It draws a dashed line on the canvas. This helps if there are multiple lines on top of each other.
2015-10-19 16:45:16 +02:00
Ghostkeeper 7524df2868 Add yellow colour to SVG
I needed an extra colour for debugging. Why not yellow?
2015-10-19 16:43:55 +02:00
Ghostkeeper 28ac5dc2c9 Switch X to be the horizontal dimension
This was the wrong way around in everything except my writeLines function. X is commonly the horizontal dimension (even in the SVG language itself).
2015-10-19 13:58:25 +02:00
Ghostkeeper f5db2ee8b4 Merge master to 15.10
I need the new writeLines in SVG debugging. I know it's not really a bugfix, but SVG is not used in actual releases, so it would not break anything.
2015-10-19 11:46:09 +02:00
Tim Kuipers 8e736f32aa LayerBuffer bugfixes 2015-10-16 16:11:39 +02:00
Tim Kuipers 9b4d93e236 getSettingAsFlowTempGraph 2015-10-16 15:38:33 +02:00
Ghostkeeper 2f4316e755 Fix infill if too few layers
I just introduced a bug where if there were too few layers such that no infill is generated at all, the infill combining would take a practically infinite amount of time. The cause was an underflow. This fixes it.
2015-10-16 13:55:56 +02:00
Ghostkeeper 52e5b33e7e Remove debug includes
These two includes were used to debug the combing, but they shouldn't have been committed.
2015-10-16 13:45:38 +02:00
Ghostkeeper 01c124774c Merge branch 'master' of https://github.com/Ultimaker/CuraEngine 2015-10-16 13:35:43 +02:00
Ghostkeeper b4afc8bb4f Narrow range of combining infill layers
Infill layers only need to be combined between <bottom_layers> and <N - 1 - top_layers>. This theoretically makes the code a bit faster. Also, the infill is now combined from 0 upwards rather than in reverse order, and renamed layer_index to layer_idx.
2015-10-16 13:30:46 +02:00
Tim Kuipers d4e2f774db parse array settings 2015-10-16 13:28:33 +02:00
Tim Kuipers eb388c7d80 parse json arrays 2015-10-16 13:28:26 +02:00
Tim Kuipers ab5b7f432e unindeted wrongly indented function 2015-10-16 13:28:17 +02:00
Tim Kuipers e0a09dbe7c parse array settings 2015-10-16 13:20:32 +02:00
Tim Kuipers d83863ce4c parse json arrays 2015-10-16 13:20:17 +02:00
Tim Kuipers fe8def059e unindeted wrongly indented function 2015-10-16 12:09:20 +02:00
Ghostkeeper b91abb4c22 Don't process nonexistent file
If the file you're trying to load doesn't exist, don't add an empty mesh to the mesh group, and don't try to slice that mesh.
2015-10-16 10:40:33 +02:00
Tim Kuipers 4179e46a9d insert preheat command into extruderplan and compute temp from graph 2015-10-16 10:28:24 +02:00
Tim Kuipers 692e875256 more layerPlanBuffer refactor and computation of where to insert the preheat command 2015-10-15 18:58:50 +02:00
Tim Kuipers 9d513291ba used iterator instead of complicated nested for loop bs 2015-10-15 18:41:21 +02:00
Tim Kuipers 5b0370864b syntax mistake fixes 2015-10-15 18:34:21 +02:00
Tim Kuipers 4dcb8563f5 more LayerBuffer crap 2015-10-15 18:32:10 +02:00
Tim Kuipers 21b6be76fe introduced buffer.iterator 2015-10-15 18:28:35 +02:00
Tim Kuipers f06fa4af1a special case for when the first extruder plan of a layer is with the same extruder as the last extruder plan of the previous layer 2015-10-15 18:05:53 +02:00
Tim Kuipers 951eac4c08 config per extruder 2015-10-15 18:05:02 +02:00
Tim Kuipers e4e2dc172e flow-temp graph class 2015-10-15 17:41:22 +02:00
Tim Kuipers 70b0800f2e insertPreheatCommands first approximation 2015-10-15 17:19:32 +02:00
Tim Kuipers aaaf2a6c92 Preheat file first approximation 2015-10-15 17:18:58 +02:00
Ghostkeeper bde136e7ed Fix failed merge
I picked the wrong one to resolve the conflict.
2015-10-15 16:53:42 +02:00
Ghostkeeper 75859623d7 Remove duplicate points from comb path
This sometimes produced zero-length moves at the beginning and end of combing paths.
2015-10-15 16:37:34 +02:00
Ghostkeeper 388a65ef11 Fix combing optimisation intersection bug
The intersections of the line and the polygons was not offset with the extra offset distance to prevent edge cases. This concerns issue #259.
2015-10-15 16:37:34 +02:00
Ghostkeeper 1168c2b120 Document edge cases in line-polygon intersection
It is documented that basically all edge cases trigger a collision.
2015-10-15 16:37:34 +02:00
Ghostkeeper dfd31844ba Handle edge cases for line-polygon collision properly
If a line doesn't intersect but does touch a polygon, a collision is now triggered. This is the desired behaviour in this case, since this method is only used by the combing code.
2015-10-15 16:37:34 +02:00
Ghostkeeper f457f2590c Add writeLines
This draws a polyline on the canvas, which is a sequence of connected line segments. This helps visualising paths.
2015-10-15 16:37:33 +02:00
Ghostkeeper fb9bcccbbe Fix writeLine to transform the points
The transform scales the line to the proper scale, to match the scale of the viewport.
2015-10-15 16:37:33 +02:00
Ghostkeeper cfe216ae44 Merge master onto a41a1e5
Modified files:
    src/gcodeExport.cpp
2015-10-15 16:36:21 +02:00
Tim Kuipers a41a1e556a merge 2015-10-15 11:56:01 +02:00
Tim Kuipers 8081237298 merge 2015-10-15 11:54:33 +02:00
Tim Kuipers 1a7137a6c8 bugfix: make all varargs functions use rvalues - fixes the varargs functions making copies of the objects which are passed by reference 2015-10-15 11:52:22 +02:00
Tim Kuipers 4c967ec6a3 buggy layer buffer used 2015-10-15 09:22:55 +02:00
Tim Kuipers b455661a75 moved processFanSpeedAndMinimalLayerTime outside of gcodePlanner.writeGcode 2015-10-14 14:17:17 +02:00
Tim Kuipers 46b7d1ccab keep time and material info at each GCodePath and each ExtruderPlan 2015-10-14 13:54:29 +02:00
Tim Kuipers fb95022776 assert fix 2015-10-14 11:45:44 +02:00
Tim Kuipers 62ce0b5513 changed starting position to 0,0,20mm 2015-10-14 11:35:15 +02:00
Tim Kuipers 12c25b2214 Revert "added no_point instead of (0,0)"
This reverts commit f49803b8a9.
2015-10-14 11:33:33 +02:00
Tim Kuipers 61915fc322 bugfix: raft is now uses combing, instead of retracting everywhere 2015-10-14 10:57:01 +02:00
Tim Kuipers aa1998dbd8 halfway bugfix: combing during raft 2015-10-14 10:56:36 +02:00
Hajo Nils Krabbenhöft 859a106ec2 rework getLayerSecondWalls() to make sure it doesn't completely remove isles with less than 0.8mm radius (= offset_from_outlines = 2*nozzle_size) 2015-10-14 10:54:34 +02:00
Tim Kuipers ff38534644 bugfix: raftmargin was ignored 2015-10-14 10:45:56 +02:00
Tim Kuipers 2eb81d216f manual merge for raft z 2015-10-14 10:45:31 +02:00
Ghostkeeper 2785659fe6 Move layer loop into combineInfillLayers
The combineInfillLayers function now loops over all layers and combines them. The function therefore no longer needs to be called for every layer.
2015-10-14 10:07:31 +02:00
Ghostkeeper 4bc86ad192 Compute combined infill layers only on modulo-0 layers
For instance, if the sparse_infill_combine setting is 3, it will only be computed for layers 0, 3, 6, etc. This prevents different parts of infill from landing on different layers, causing infill to break into multiple layers.
2015-10-14 10:07:22 +02:00
Tim Kuipers a7b5e05505 bugfix: support roofs sendPolygons now of type SupportType 2015-10-14 10:03:49 +02:00
Tim Kuipers 0fd130cfd3 bugfix: support roof config and support roof sendPolygons(.) 2015-10-14 10:03:33 +02:00
Tim Kuipers ccae7d611e bugfix: timeEstimate recalculate trapezoids failed 2015-10-14 10:02:45 +02:00
Arjen Hiemstra 5dcce74efe Increment layer count for each object that should be printed as a single object
This makes the ordering for one-at-a-time mode more clear

CURA-222 #Start-Review
2015-10-13 17:54:25 +02:00
Tim Kuipers 988af0f6ed (buggy dual extr) refactor: gcodePlanner now consists of ExtruderPlan s which consist of Path s 2015-10-13 15:39:30 +02:00
Tim Kuipers 53714319b4 more work on buffer.insertPreheatCommands 2015-10-13 13:57:28 +02:00
Tim Kuipers fe44537924 Merge branch 'master' into feature_temp_compensation_gcodePlanner 2015-10-13 13:14:31 +02:00
Tim Kuipers a285b22804 reintroduced initial layer height when raft is present 2015-10-13 12:33:03 +02:00
Tim Kuipers e588fe100b Merge branch 'master' of https://github.com/Ultimaker/CuraEngine 2015-10-13 12:01:26 +02:00
Tim Kuipers ad81cc8a12 bugfix: raft is now uses combing, instead of retracting everywhere 2015-10-13 12:01:16 +02:00
Tim Kuipers a3db17442c halfway bugfix: combing during raft 2015-10-13 10:49:19 +02:00
Tim Kuipers e0cf567bf7 bugfix: raftmargin was ignored 2015-10-13 09:55:07 +02:00
Tim Kuipers 904ad24eec bugfix: raft z was computed as if it was a normal layer 2015-10-13 09:47:06 +02:00
Tim Kuipers f49803b8a9 added no_point instead of (0,0) 2015-10-09 17:22:45 +02:00
Tim Kuipers 2b422ce6c0 debug output command socket transmitted data as STL 2015-10-09 15:33:56 +02:00
Ghostkeeper b2cc46a4cb Move layer loop into combineInfillLayers
The combineInfillLayers function now loops over all layers and combines them. The function therefore no longer needs to be called for every layer.
2015-10-09 13:45:39 +02:00
Ghostkeeper 98d105d73c Compute combined infill layers only on modulo-0 layers
For instance, if the sparse_infill_combine setting is 3, it will only be computed for layers 0, 3, 6, etc. This prevents different parts of infill from landing on different layers, causing infill to break into multiple layers.
2015-10-09 10:45:39 +02:00
Tim Kuipers ecd32700f5 lil bugfixes 2015-10-08 16:01:57 +02:00
Ghostkeeper 44c77d2a31 Add Netbeans project file to gitignore
Also categorised the ignore file. Only the "nbproject/*" is new.
2015-10-08 15:35:35 +02:00
Hajo Nils Krabbenhöft f78c3ed4da thicker lines for retraction moves 2015-10-08 15:30:07 +02:00
Hajo Nils Krabbenhöft 79b16e406a GCodePlanner will initialize command socket on GCodeExport, which will then send combing and retraction paths to GUI 2015-10-08 15:30:07 +02:00
Hajo Nils Krabbenhöft 8219f32d96 also add new poly types to cpp backend 2015-10-08 15:30:07 +02:00
Hajo Nils Krabbenhöft 05cfe62927 add new types to protobuf 2015-10-08 15:30:07 +02:00
Ghostkeeper 38e832c172 Move documentation to header file
This documentation should be in the header, as per the code style conventions and for Doxygen.
2015-10-08 15:12:51 +02:00
Tim Kuipers 64ef6e5698 first approximation of the layer plan buffer 2015-10-08 14:49:33 +02:00
Tim Kuipers 769dc252df coding conventions: Pointers vs. references 2015-10-08 11:22:50 +02:00
Tim Kuipers 7093231707 auto-merge fixes 2015-10-07 16:32:25 +02:00
Tim Kuipers ad93a8adde cleanup: no more use of gcode.startPosition; moved gcode.setZ(.) from FffGcodeWriter to gcodePlanner.writeGcode(.) 2015-10-07 16:24:39 +02:00
Tim Kuipers 1bb8bde1de TODO warning; is this code very unsafe maybe? 2015-10-07 15:52:06 +02:00
Tim Kuipers d6822cdaf8 bugfix: processFanSpeedAndMinmalLayerTime was commented 2015-10-07 14:59:25 +02:00
Tim Kuipers 2817528c51 undoing gcodePlanner buffer edits from the commits from the feature_temp_compensation_gcodePlanner branch 2015-10-07 14:58:33 +02:00
Tim Kuipers a52f101c14 fully purged gcodePlanner from references to gcodeExport: moved current position and current extruder to FffGcodeWriter 2015-10-07 14:51:07 +02:00
Tim Kuipers 22b1d427ec forgot to add a header file in last commit 2015-10-07 14:49:33 +02:00
Tim Kuipers b89733320d purged gcodePlanner from references to gcodeExport: moved processFanSpeedAndMinimalLayerTime and factored out lastPosition=gcode.gettPositionXY(); introduced very basic gcodePlanner buffering 2015-10-07 14:09:44 +02:00
Tim Kuipers f662844d78 bugfix: support roofs sendPolygons now of type SupportType 2015-10-07 10:23:37 +02:00
Tim Kuipers 38a4e45771 bugfix: support roof config and support roof sendPolygons(.) 2015-10-06 15:16:43 +02:00
Tim Kuipers dc87dda346 Merge pull request #255 from nicanor-romero/15.10
Explicitly write a \n when finding a new line in a comment
2015-10-06 14:17:52 +02:00
Nicanor Romero Venier f249796f3d Explicitly write a \n when finding a new line in a comment
This way the start_gcode and end_gcode that includes '\n's will not
have their commands executed since they now appear as commented out.
2015-10-06 13:05:00 +02:00
Tim Kuipers 9602616a6b bugfix: timeEstimate recalculate trapezoids failed 2015-10-02 17:01:32 +02:00
Tim Kuipers 0823f8faf5 syntax fixes of last merge 2015-10-01 15:46:17 +02:00
Tim Kuipers 33d63e8359 Merge branch '15.10'
Conflicts:
	src/FffGcodeWriter.cpp
	src/gcodePlanner.cpp
2015-10-01 15:44:20 +02:00
Tim Kuipers 3a8a5844d4 moved file 'new settings master' 2015-10-01 15:08:55 +02:00
Tim Kuipers 7b5bb1e367 write 'end of gcode' comment at end of gcode 2015-10-01 11:18:00 +02:00
Tim Kuipers 017dc5be4c bugfix: profile string caused bugs on UMO and when USB printing 2015-10-01 11:14:18 +02:00
Tim Kuipers 60c9e83da9 bugfix: double skin areas 2015-09-30 16:18:26 +02:00
Tim Kuipers 51927938b0 bugfix: visualization used support areas instead of lines 2015-09-30 12:31:03 +02:00
Tim Kuipers d4b9f7c0bd Merge branch '15.10' of https://github.com/Ultimaker/CuraEngine into 15.10 2015-09-30 09:43:58 +02:00
Tim Kuipers 0b78099587 bugfix: coasting speeds were 100 times too much (%) 2015-09-30 09:43:46 +02:00
Arjen Hiemstra a61d5385ea Use size_t instead of "long unsigned int" for storing vector sizes
std::vector<>::size() returns a size_t. size_t is a long uint on 64-bit
but a normal uint on 32-bit. So compilation on 32-bit fails because
std::max cannot do template deduction correctly.
2015-09-29 17:52:02 +02:00
Tim Kuipers 24c836f87a Merge branch '15.10' of https://github.com/Ultimaker/CuraEngine into 15.10 2015-09-29 16:14:50 +02:00
Tim Kuipers 8a2ca62305 bugfix: retractions on any move smaller than the retraction_min_travel when combing was disabled 2015-09-29 16:14:40 +02:00
Arjen Hiemstra b0ae307006 Fix check for "touching buildplate" option of support type
CURA-168 #done
2015-09-29 16:09:06 +02:00
Hajo Nils Krabbenhöft 29dd62345a use int for zhop 2015-09-29 15:49:34 +02:00
Hajo Nils Krabbenhöft b3f555c78f store current z-hop height and keep applying that on multi-step travel 2015-09-29 15:49:25 +02:00
Tim Kuipers 0b2f64c6a7 bugfix: total_layers count 2015-09-29 14:44:50 +02:00
Tim Kuipers d501fe67d5 refactor: totalLayers -> total_layers 2015-09-29 14:41:12 +02:00
Tim Kuipers 7180e77699 refactor: fixed enum FillPerimeterGapMode to match other enums 2015-09-29 11:04:04 +02:00
Olliver Schinagl 9c36fdf513 GCodeExport: (re-)Add layer_count tag
Commit 1070d36 broke the build by enabeling code that was not kept up to
date, this patch fixes it properly by adding the
writeLayerCountComment() method.

Signed-off-by: Olliver Schinagl <o.schinagl@ultimaker.com>
2015-09-29 11:03:35 +02:00
Tim Kuipers bc8a167e7b refactor: fixed enum FillPerimeterGapMode to match other enums 2015-09-29 11:03:32 +02:00
Olliver Schinagl a2881b83f7 GCodeExport: (re-)Add layer_count tag
Commit 1070d36 broke the build by enabeling code that was not kept up to
date, this patch fixes it properly by adding the
writeLayerCountComment() method.

Signed-off-by: Olliver Schinagl <o.schinagl@ultimaker.com>
2015-09-29 10:25:35 +02:00
Olliver Schinagl bd90dd060f Re-nable layer count using a consistent tag name
Signed-off-by: Olliver Schinagl <o.schinagl@ultimaker.com>
2015-09-28 17:37:03 +02:00
Olliver Schinagl 1070d367e1 Re-nable layer count using a consistent tag name
Signed-off-by: Olliver Schinagl <o.schinagl@ultimaker.com>
2015-09-25 12:04:19 +02:00
Arjen Hiemstra 5ac62a96a8 Also fix another call for Fill Perimeter Gaps
Contributes to Ultimaker/Cura#411
2015-09-22 12:38:53 +02:00
Arjen Hiemstra 7010689448 Fix "Fill Perimeter Gaps" to properly check values
Since the enum values were changed to normalised values this check was
wrong. Additonally, now properly use an Enum for the values since that
is a cleaner approach.

Fixes Ultimaker/Cura#411
2015-09-22 12:37:03 +02:00
Jaime van Kessel 869975be6b Merge pull request #247 from fxtentacle/15.10-retract-when-no-combing
always retract when combing is disabled
2015-09-22 09:57:23 +02:00
Hajo Nils Krabbenhöft da3bf8da32 always retract when combing is disabled 2015-09-22 09:53:11 +02:00
Jaime van Kessel e861fba11b Merge pull request #246 from fxtentacle/fix-retraction-for-small-isles
fix retraction for isles < 0.8mm radius
2015-09-21 21:22:58 +08:00
Hajo Nils Krabbenhöft 226c974b5f rework getLayerSecondWalls() to make sure it doesn't completely remove isles with less than 0.8mm radius (= offset_from_outlines = 2*nozzle_size) 2015-09-21 14:14:18 +02:00
Jaime van Kessel b25c72a9e3 Merge pull request #245 from fxtentacle/fix-zhop-2
Keep Z-Hop active for multi-step moves
2015-09-21 18:06:25 +08:00
Hajo Nils Krabbenhöft 6caf2b2db9 instead of the hardcoded 1.5mm, use last_retraction_config->retraction_min_travel_distance as threshold 2015-09-21 12:01:57 +02:00
Hajo Nils Krabbenhöft b6138cb951 replace hardcoded Comb::max_comb_distance_ignored = 1.5mm with function parameter, which defaults to 1.5mm 2015-09-21 12:00:37 +02:00
Jaime van Kessel e9b0cfc939 Merge pull request #244 from fxtentacle/retract-when-no-combing2
always retract when combing is disabled
2015-09-21 17:34:08 +08:00
Hajo Nils Krabbenhöft f6e44af43d use int for zhop 2015-09-21 11:33:09 +02:00
Hajo Nils Krabbenhöft 487f35abd4 store current z-hop height and keep applying that on multi-step travel 2015-09-21 11:33:09 +02:00
Jaime van Kessel 2a163528f9 Merge pull request #242 from fxtentacle/master
send travel moves to GUI from GCodeExport
2015-09-21 17:32:08 +08:00
Hajo Nils Krabbenhöft 02e6c87396 always retract when combing is disabled 2015-09-21 11:31:59 +02:00
Hajo Nils Krabbenhöft b367af6ad1 thicker lines for retraction moves 2015-09-21 00:17:02 +02:00
Hajo Nils Krabbenhöft eef8b77405 GCodePlanner will initialize command socket on GCodeExport, which will then send combing and retraction paths to GUI 2015-09-21 00:11:07 +02:00
Hajo Nils Krabbenhöft 97a4c00022 also add new poly types to cpp backend 2015-09-20 23:23:41 +02:00
Hajo Nils Krabbenhöft 6516ae0da9 add new types to protobuf 2015-09-20 23:16:07 +02:00
Arjen Hiemstra 360e3d7e24 Fix one-at-a-time mode so it does not stop after printing 1 object
CURA-162:review
CURA-190:review
2015-09-18 12:09:08 +02:00
Tim Kuipers c267492a48 bugfix: raft viz 2015-09-10 13:20:44 +02:00
Tim Kuipers 52258e2d3a bugfix: send polygon info after fuzzy skin 2015-09-10 11:44:43 +02:00
Tim Kuipers 92c6edca86 bugfix: send polygon info after fuzzy skin 2015-09-10 11:40:26 +02:00
Tim Kuipers 9c26c820a9 bugfix: skin line distance was infill line width 2015-09-10 11:20:40 +02:00
Tim Kuipers b7993441ff bugfix: support progress was still wrong per object 2015-09-10 10:22:06 +02:00
Tim Kuipers 10ebc96323 bugfix: no bottom/top layers resulted in a lingle layer 2015-09-09 17:06:08 +02:00
Tim Kuipers 13af50f34d Merge branch '15.10' of https://github.com/Ultimaker/CuraEngine into 15.10 2015-09-09 16:52:25 +02:00
Tim Kuipers 0563c6eacc Merge branch 'bugfix_per_object_support' into 15.10 2015-09-09 15:26:54 +02:00
Tim Kuipers ab313b8992 doc: explanations on support 2015-09-09 14:18:38 +02:00
Tim Kuipers 7779bb9604 bugfix: support roofs per object 2015-09-09 13:54:18 +02:00
Tim Kuipers 1576d1d19e bugfix: normal support per object 2015-09-09 13:23:17 +02:00
Tim Kuipers 615ed0b384 README now has correct call method 2015-09-09 11:00:29 +02:00
Arjen Hiemstra 6f95a78f3c Set correct RPATH for CuraEngine 2015-09-08 17:29:25 +02:00
Tim Kuipers ae79d232f3 bugfixes for skin extrusion width; feature: toggle skin_no_small_gaps_heuristic 2015-09-08 16:25:21 +02:00
Tim Kuipers 11786ada66 lil change fuzzy mode 2015-09-08 12:35:24 +02:00
Tim Kuipers 648bc1f3f3 bugfix: fuzzy skin had too many points; redux can lead to not enough points on poly 2015-09-08 12:35:16 +02:00
Tim Kuipers 84be436eb9 feat: fuzzy skin magic mode 2015-09-08 12:35:06 +02:00
Tim Kuipers e04965187a bugfix: visualize skin lines instead of areas 2015-09-08 10:34:53 +02:00
Tim Kuipers ee09c6da92 lil change fuzzy mode 2015-09-04 10:10:58 +02:00
Tim Kuipers 325345a2ce bugfix: fuzzy skin had too many points; redux can lead to not enough points on poly 2015-09-03 19:15:40 +02:00
Tim Kuipers 29e17d8bdf feat: fuzzy skin magic mode 2015-09-03 18:33:15 +02:00
Tim Kuipers 1f1bfadf9e basic priliminary functionality for tracking print time per feature; safety assertions in writemove(.) which work for UM2 2015-09-03 14:22:41 +02:00
Tim Kuipers 5aca2bde45 bugfix: speeds were too high for merged infill lines 2015-09-03 14:16:38 +02:00
Tim Kuipers ae6426cb6e Merge branch 'master' of https://github.com/Ultimaker/CuraEngine 2015-09-02 13:29:34 +02:00
Arjen Hiemstra 7271693169 Normalize enum value names to reflect changes in the JSON file
We now store options as (key => user visible string) in the json file.
The keys in the json file have been normalized. Now the engine also
reflects that change.
2015-09-01 18:20:22 +02:00
Tim Kuipers d5bbe57571 magic_mesh_surface_mode setting refactor registered 2015-09-01 15:28:11 +02:00
Tim Kuipers 8423d3ed4a lil 2015-08-31 17:09:20 +02:00
Tim Kuipers b1f717ad9b refactor: moved processOozeShield 2015-08-31 15:07:37 +02:00
Tim Kuipers 00eba89494 refactor: made all enums conformant 2015-08-31 14:48:59 +02:00
Tim Kuipers 76e5b8b94b split magic_mesh)surface_mode into Normal, Surface, Both 2015-08-31 14:31:28 +02:00
Tim Kuipers 80e09a05ef lil bugfix: typo in FffPolygonGenerator.cpp 2015-08-31 13:06:58 +02:00
Tim Kuipers e96bd68324 bugfix: SliceDataStorage::getLayerOutlines used ungenerated support 2015-08-31 13:05:36 +02:00
Tim Kuipers 9ba6239219 bugfix: ooze shield was computed before support 2015-08-31 13:04:52 +02:00
Tim Kuipers af099e6896 used SliceDataStorage::getLayerOutlines(.) for raft, skirt, oozeShield, draftShield, combing 2015-08-31 12:36:34 +02:00
Tim Kuipers bcdcc25a51 offsetPolyline(.) 2015-08-31 12:30:54 +02:00
Tim Kuipers 6b9c98914d SliceDataStorage::getLayerOutlines 2015-08-31 12:30:07 +02:00
Tim Kuipers e1d508ade0 bugfix: no support for meshes without insets 2015-08-31 12:28:49 +02:00
Tim Kuipers 919c0ea16d better visualization mesh surface mode and removeEmptyFirstLayers now takes mesh surface mode into account 2015-08-28 16:56:41 +02:00
Tim Kuipers 865b22063b better visualization mesh surface mode 2015-08-28 16:51:46 +02:00
Tim Kuipers 4bfd48efa7 bugfixes: uninitialized support.generated; uninitialized primeTower.extruder_count; layer_nr_max_filled_layer didnt account for mesh surface mode; refactored all magic_polygon_mode to mesh_surface_mode; bugfix mesh surface mode: tried to write lines as polygons 2015-08-28 16:44:08 +02:00
Tim Kuipers 9e2b269c8b refactor: slicer and mesh surface mode names; starting mesh surface mode debug 2015-08-28 11:42:09 +02:00
Tim Kuipers 2e78d60c13 disable comb boundary for magic mesh surface mode or spiralize 2015-08-28 10:20:38 +02:00
Tim Kuipers caf1fd5582 disable comb boundary for magic mesh surface mode or spiralize 2015-08-28 10:20:18 +02:00
Tim Kuipers 8f99483d2c bugfix: moveinside called for spiralize vase 2015-08-28 10:16:26 +02:00
Tim Kuipers fc31b13a5e infill visualized area, not lines... 2015-08-27 14:49:05 +02:00
Tim Kuipers 2ea1bc0e59 refactor: renamed all sparse infill to infill 2015-08-27 14:32:24 +02:00
Tim Kuipers 102fb24d74 bugfix: no infill visualization 2015-08-27 14:26:01 +02:00
Tim Kuipers 381bf1c3d2 bugfix: min area size for infill and skin were too large 2015-08-27 14:17:58 +02:00
Tim Kuipers 03b188aca5 bugfix: now always appending cura profile string 2015-08-27 12:32:10 +02:00
Tim Kuipers d584b19078 refcator: moved FffProcessor.h functions to cpp 2015-08-27 12:24:47 +02:00
Tim Kuipers df1b0372ff refactor: rename fffProcessor to FffProcessor 2015-08-27 12:20:51 +02:00
Tim Kuipers 73de8ac75b made fffProcessor singleton 2015-08-27 12:19:13 +02:00
Tim Kuipers 48464e9d13 feat: cura settings string to log and end of gcode (when not using commandSocket) 2015-08-27 11:15:53 +02:00
Tim Kuipers 51a9d1b44f feat/bugfix: implemented missing -g command line option (switch to meshgroup) 2015-08-27 10:27:06 +02:00
Tim Kuipers 481142ef4a lil cleanup 2015-08-26 16:20:34 +02:00
Tim Kuipers 2eb3d3438a Merge branch 'master' of https://github.com/Ultimaker/CuraEngine 2015-08-26 15:15:08 +02:00
Tim Kuipers eedda865bc feat: settings registry handles overrides; refactor: SettingConfig inherits from SettingsContainer (was SettingsCategory) 2015-08-26 15:14:59 +02:00
Tim Kuipers d9195c276f settingRegistry handles json document inheritance 2015-08-26 15:11:56 +02:00
Tim Kuipers 5accc6adf8 feat: json settings loader now uses recursion to load other json files 2015-08-26 11:34:18 +02:00
Tim Kuipers f7fde50e73 print call when erroneous cpommand line parsing 2015-08-26 10:31:51 +02:00
Tim Kuipers 765b8be00b bugfix: retraction at end of gcode! 2015-08-26 09:57:18 +02:00
Tim Kuipers 756af8601c feat: infill before walls 2015-08-25 16:18:39 +02:00
TotalRetribution 6a26649fe4 Merged and fixed Conflict with outer_inset_first option in src/FffGcodeWriter.cpp 2015-08-25 15:12:28 +01:00
Tim Kuipers 21661f2f4b lil 2015-08-25 14:36:35 +02:00
Tim Kuipers 1ffa57f740 enabled support roof configurable pattern and line distance 2015-08-25 13:29:39 +02:00
Tim Kuipers 158b944b76 bugfix: concentric dense infill never called 2015-08-25 13:29:07 +02:00
Tim Kuipers cce2efd419 refactor: fill of any sort (skin, support, infill) moved to infill.cpp 2015-08-25 13:09:19 +02:00
Tim Kuipers 1853a41117 made polygonUtils work on const polygons 2015-08-25 13:08:39 +02:00
Tim Kuipers 69412eda52 bugfix: support tried to message polygons while support wasnt generated 2015-08-25 10:35:44 +02:00
Tim Kuipers 567c385e69 introduced generateInfill(pattern, ...) 2015-08-25 10:06:20 +02:00
Tim Kuipers e35f21ef7b bugfix: disable retraction (set to 0) when retraction not enabled 2015-08-24 17:19:04 +02:00
Tim Kuipers ee8b2ed39c bugfix: disable retraction (set to 0) when retraction not enabled 2015-08-24 17:18:33 +02:00
Tim Kuipers 7d93688b9b removed allways_retract and moved some calls to setCombing to the right place 2015-08-24 17:14:34 +02:00
Tim Kuipers 8daa32f757 bugfix: layer height info sent before beginSendSlicedObject called 2015-08-24 16:15:19 +02:00
Tim Kuipers cf05eadfaa polygon settings loading skipped (temp fix) 2015-08-24 13:55:02 +02:00
Tim Kuipers 70093fdb5a feat/bugfix: z seam placement: back,random or shortest (not yet the aligned) 2015-08-24 12:03:44 +02:00
Tim Kuipers 1a7dec654e temp file recording the setting changes between master and 15.06 2015-08-24 10:07:55 +02:00
TotalRetribution 5334fb881e Merge remote-tracking branch 'origin/master' into reverse_inset_order 2015-08-21 15:49:01 +01:00
Tim Kuipers 24f41fe419 refactored calculateMeshorder so that it returns indices instead of the meshes, debug code for z seam in FffGcodeWriter::processInsets 2015-08-20 17:07:31 +02:00
Tim Kuipers 97e89e1a94 bugfix: moveInside didn't want to move inside by default 2015-08-20 16:51:50 +02:00
Tim Kuipers 913f955de8 refactor: moved all polygonUtils into class PolygonUtils with all static methods 2015-08-20 14:24:23 +02:00
Tim Kuipers a2fa27603b simplify: decoupled error_dist from smallest_line_length 2015-08-20 14:10:11 +02:00
Tim Kuipers 9d313910f4 removed debug test main 2015-08-20 14:09:35 +02:00
Tim Kuipers eacc87d435 bugfix: simplify would in some cases move the end point of a long line if it is followed by a lot of small segments 2015-08-20 12:46:37 +02:00
Tim Kuipers 57f276d07e bugfix: simplify would in some cases move the end point of a long line if it is followed by a lot of small segments 2015-08-20 12:36:39 +02:00
Tim Kuipers dd638c32e5 bugfixes: now fully removed polygonOptimizer and finished getDist2FromLineSegment 2015-08-20 12:22:39 +02:00
Tim Kuipers e02ed7c928 removed function [Polygons simplified(args..)] and left [void simplify(args..)] 2015-08-20 12:21:09 +02:00
Tim Kuipers c0007b156f improved getDist2FromLineSegment: may have extra output parameter 2015-08-20 12:16:21 +02:00
Tim Kuipers 2c1f4cf50e removed polygonOptimizer 2015-08-20 12:02:31 +02:00
Tim Kuipers 28612e060c replaced optimizePolygons by simplify 2015-08-20 12:01:40 +02:00
Tim Kuipers 094370db73 refactor: made LinearAlg2D a class with static methods and moved getClosestOnLineSegment to it 2015-08-20 11:22:44 +02:00
Tim Kuipers ecb6b7c914 have doxygen generate dependency graphs etc. 2015-08-20 10:50:00 +02:00
Tim Kuipers 51b2d390c5 includes cleanup main.cpp 2015-08-20 10:46:40 +02:00
Tim Kuipers be157338ad buggy simplify improvement; bug = circular include? 2015-08-20 10:09:29 +02:00
Tim Kuipers 2c54394cd0 removed polygondebug > moved to SVG.h 2015-08-19 14:27:10 +02:00
Tim Kuipers 141f29bc18 centralized SVG output file (debug) 2015-08-19 14:25:59 +02:00
Tim Kuipers 28b27c971e bugfix: AABB perfomred totally unnecessary copies! 2015-08-19 12:23:41 +02:00
TotalRetribution bc9d7aced8 Added: Option to print outer inset first. 2015-08-19 10:35:09 +01:00
TotalRetribution 5bb794dc91 Merge remote-tracking branch 'origin/master' into reverse_inset_order
Conflicts:
	src/fffProcessor.h
	src/settings.cpp
	src/settings.h
2015-08-19 10:32:04 +01:00
Tim Kuipers 7efc41e218 Merge branch 'master' of https://github.com/Ultimaker/CuraEngine 2015-08-19 11:12:33 +02:00
Tim Kuipers 7145023b6f lil 2015-08-19 11:12:24 +02:00
Tim Kuipers 8797157351 bugfixes: combing: nor combing during raft, skirt, support, etc. ; not trying to move inside comb boundary when not combing ; skip some trying-to-comb for some travel moves by calling directly addTravel_simple instead of addTravel 2015-08-19 11:11:34 +02:00
Arjen Hiemstra f999e1b75f Extend per-object setting support to MeshGroup 2015-08-18 18:20:12 +02:00
Tim Kuipers 5876964d41 refactor: fill_ > infill_ 2015-08-18 11:49:08 +02:00
Tim Kuipers 61ff30772c bugfix: skin used perimeter overlap; feature: move inside after each layer part 2015-08-17 14:43:38 +02:00
Tim Kuipers e6453082bf bugfix: UMO bed temp error when there is no heated bed 2015-08-14 17:17:32 +02:00
Tim Kuipers c2038f7408 coasting config per mesh 2015-08-14 16:16:17 +02:00
Tim Kuipers ff5a1d82f8 comb offset not depending on general wall line width anymore 2015-08-14 15:11:56 +02:00
Tim Kuipers 1b13dfca97 fixed outer wall width and placement and distinguished between outer wall smaller or larger than nozzle size 2015-08-14 13:48:09 +02:00
Tim Kuipers fed536b079 fixed outer wall width and placement 2015-08-14 12:45:22 +02:00
Tim Kuipers 3cf74b5624 initial_layer_speed per mesh 2015-08-14 12:29:58 +02:00
Tim Kuipers 52a57b1499 moved retractionMinimalDistance, retraction_extrusion_window, retraction_count_max into RetractionConfig 2015-08-14 11:55:02 +02:00
Tim Kuipers 831266db31 retraction config per mesh, retraction config per extruder 2015-08-13 17:01:20 +02:00
Tim Kuipers 5fdb56966f get some settings per mesh instead of from general settings 2015-08-13 13:35:21 +02:00
Tim Kuipers eae4c507a4 optimization: no mesh offset is offset is zero 2015-08-13 13:33:36 +02:00
Tim Kuipers 92b68c5745 mesh positioning retrieved per object 2015-08-13 13:33:04 +02:00
Tim Kuipers 9ade99a9c7 renamed extruder_switch_retract settings and support_extruder_nr_layer_0 2015-08-13 10:31:06 +02:00
Tim Kuipers 097c390fab enabled print time again 2015-08-13 08:48:37 +02:00
Tim Kuipers f982202aa4 bugfix: extruder offset enabled when should have been disabled, and vice versa! (The heat is getting to me) 2015-08-12 15:36:39 +02:00
Tim Kuipers c3f474e229 Revert "refactor: pulled writePath out of GCodePlanner::writeGCode"
This commit introduced major bugs.

This reverts commit 125af2915f.
2015-08-12 15:19:23 +02:00
Tim Kuipers 125af2915f refactor: pulled writePath out of GCodePlanner::writeGCode 2015-08-12 12:31:35 +02:00
Tim Kuipers 7b26d08d25 lil optimization: earlier travel path gcode generation 2015-08-12 12:20:44 +02:00
Tim Kuipers a2b631b61b bugfix: infill lines merger ignored travel path before it 2015-08-12 12:16:30 +02:00
Tim Kuipers e3df22dab9 combing debug, bugfixes, enhancements 2015-08-12 11:27:53 +02:00
Tim Kuipers 7ad1b32ef3 feat: optimization: one less copy if inset is already computed 2015-08-11 17:21:48 +02:00
Tim Kuipers 98a7c65d66 bugfix: no return when GCodePlanner::makeRetractSwitchRetract reached end of all paths in gcode_layer 2015-08-11 16:15:38 +02:00
Tim Kuipers b60ad09882 bugfix: combing crossed perimeters due to starting points being too close to a perimeter; they weren't moved inside the polygons 2015-08-11 13:43:38 +02:00
Tim Kuipers 0f35450440 undoing last lil refactor, was erroneous 2015-08-11 13:17:47 +02:00
Tim Kuipers 0adc1b44e7 lil refactor 2015-08-11 11:59:28 +02:00
Tim Kuipers 8d084e727a bugfix: when skirt got doubled the second skirt line wasnt a convex hull 2015-08-11 11:25:15 +02:00
Tim Kuipers 916005b6ad feat: better conical support; new settings: support_conical_min_width, support_conical_angle 2015-08-10 16:08:57 +02:00
Tim Kuipers c7ecc23053 feat: disable xy-shifted gcode: machine_use_extruder_offset_to_offset_coords 2015-08-10 15:20:30 +02:00
Tim Kuipers 9d36987124 bugfix: disable wipe when printing prime tower with same nozzle (no nozzle switch) 2015-08-10 15:19:28 +02:00
Tim Kuipers 0fa3cab356 feature: support expansion offset 2015-08-10 14:09:53 +02:00
Tim Kuipers 31226c0b68 feat: no wipe when prime tower isn't after a nozzle switch 2015-08-10 12:08:40 +02:00
Tim Kuipers ca23a77ad0 bugfix: MergeInfillLines caused infinite speed when lines were in each others extension 2015-08-10 11:52:57 +02:00
Tim Kuipers b052cd431c bugfix: nozzle switch retractions at wrong places and too many; bugfix: removed unnecessary swaps when seconf mesh is empty at a layer 2015-08-10 10:56:08 +02:00
Tim Kuipers f00cb00f52 make last retraction of a nozzle a nozzle switch retraction 2015-08-07 16:59:41 +02:00
Tim Kuipers f236969909 bugfixes: double prime tower during skirt; wrong support order; sliceDataStorage.meshes reallocation 2015-08-07 15:30:57 +02:00
Tim Kuipers 70dde36d85 bugfix: extruder train settings overrided general setting defaults; now they have their own category in the JSON file 2015-08-06 17:14:10 +02:00
Tim Kuipers 52f8a7500e lil bugfixes: getting settings via mesh instead of general settings 2015-08-06 15:37:58 +02:00
Tim Kuipers 710138f487 different prime tower pattern 2015-08-06 15:36:32 +02:00
Tim Kuipers f7e3682c35 multi extrusion skirt 2015-08-06 13:52:42 +02:00
Arjen Hiemstra 4fca97352d Fix building on OSX since hash_fun.h does not exist there
The right header is std::hash is located in <functional>
2015-08-06 10:20:07 +02:00
Tim Kuipers 10773b688e readme 2015-08-05 14:49:21 +02:00
Tim Kuipers aae2aad42c new command line arguments handling 2015-08-05 14:45:05 +02:00
Tim Kuipers 79d36d9a49 bugfix: retraction count max; feature: switch positions 2015-08-05 14:17:47 +02:00
Tim Kuipers 96d64b325a gcodeExport: refactored all per extruder settings 2015-08-05 09:47:22 +02:00
Tim Kuipers a316302314 refactor: wire print now retrieves settings from the meshgroup 2015-08-05 09:46:46 +02:00
Tim Kuipers 93b0aad9f0 extruder train defaults per extruder train in fdmPrinter.json 2015-08-04 16:44:46 +02:00
Tim Kuipers 1df22b3cab bugfix: partsView declared as struct instead of class 2015-08-04 12:01:20 +02:00
Tim Kuipers 0a3da66539 bugfix: prime tower fixes maybe: insets 2015-07-31 17:41:59 +02:00
Tim Kuipers 45674d0b1c enhancement: prime tower improvements 2015-07-31 17:37:09 +02:00
Tim Kuipers 834a778f93 refactor: moved prime tower to PrimeTower.h and .cpp 2015-07-31 17:02:24 +02:00
Tim Kuipers 160612f0dc bugfix: setting inheritance structure is now fffProcessor>MeshGroup>ExtruderTrain>Mesh instead of fffProcessor>ExtruderTrain>MeshGroup>Mesh; feat: per object settings command line parsing, per meshgroup command line settings, per extruder train command line settings 2015-07-31 13:20:53 +02:00
Tim Kuipers 0cd463820f SliceDataStorage is now a SettingsMessenger instead of a SettingsBase 2015-07-31 13:18:56 +02:00
Tim Kuipers 73f3995443 include all files in namespace cura and standardize spelling 2015-07-31 13:16:24 +02:00
Tim Kuipers 72762d9db5 SliceDataStorage is now a SettingsMessenger instead of a SettingsBase 2015-07-31 13:15:44 +02:00
Tim Kuipers 22cbeb7c0a bugfix: virutal constructor of SettingsBaseVirtual 2015-07-31 13:14:50 +02:00
Tim Kuipers 819206afff constructors of classes extending SettingsBase now get a SettingsBaseVirtual as argument for their parent 2015-07-31 13:14:08 +02:00
Tim Kuipers 9121c5440d include all files in namespace cura and standardize spelling 2015-07-31 12:41:04 +02:00
Tim Kuipers 587121c58d bugfix: incorrectly escaped % in printf 2015-07-31 12:40:07 +02:00
Tim Kuipers 5d5912f8c2 refactor: merged the two AABB classes and renamed one to AABB3D 2015-07-31 12:33:00 +02:00
Tim Kuipers efd88d4c84 refactor: merged the two AABB classes and renamed one to AABB3D 2015-07-31 12:29:33 +02:00
Tim Kuipers c994d830fa removed empty ExtruderTrain.cpp 2015-07-31 12:26:32 +02:00
Tim Kuipers 186bdb50da per object settings 2015-07-30 17:35:34 +02:00
Tim Kuipers 2b418030bb split up main into slice() and connect() corresponding to CuraEngine slice [options] and CuraEngine connect [options] 2015-07-30 16:52:04 +02:00
Tim Kuipers 874465b450 more commandSocket clarity 2015-07-30 16:39:42 +02:00
Tim Kuipers 7089a2d72a SettingsBase split up into SettingsBaseVirtual, SettingsBase and SettingsMessenger, which only passes on settings from a parent 2015-07-30 16:37:38 +02:00
Tim Kuipers 3d7309bb3d more commandSocket clarity 2015-07-30 16:36:55 +02:00
Tim Kuipers 2f355d1263 PrimeTower.h .cpp (forgotten files), ExtruderTrain.h .cpp 2015-07-30 15:04:13 +02:00
Tim Kuipers 478c667655 different command line calls: CuraEngine slice [options] -l file OR CuraEngine connect 2015-07-30 15:03:21 +02:00
Tim Kuipers 0d07f3b9b0 temp fix: instead of sometimes reporting negative print times, always reeport a print time of 10 2015-07-30 15:01:30 +02:00
Tim Kuipers d7d3fd47f7 refactor: PrintObject => MeshGroup 2015-07-30 11:47:53 +02:00
Tim Kuipers 244a90e4eb refactoring: getting clarity on PrintObject vs Mesh 2015-07-30 11:41:45 +02:00
Tim Kuipers ec5680e2ea halfway refactoring prime tower into its own file 2015-07-30 10:44:52 +02:00
Tim Kuipers f9e562e020 removed unnecessary swaps when usign a prime tower 2015-07-30 09:29:09 +02:00
Tim Kuipers e7379efaf3 lil bugfix: support max height etc; note that unnecessary swaps don't occur anymore, but wipe tower is not added 2015-07-29 16:42:33 +02:00
Tim Kuipers 576d90806d feat: prime_tower_wipe_enabled, refactored all wipe_tower to prime_tower 2015-07-29 16:14:25 +02:00
Tim Kuipers dcedf97493 bugfix: max wipe tower height when using support roofs 2015-07-29 16:09:57 +02:00
Tim Kuipers 76af340433 bugfixes for support_roof_extruder_nr 2015-07-29 15:41:37 +02:00
Tim Kuipers 24fdcd0355 support_roof_extruder_nr 2015-07-29 14:38:58 +02:00
Tim Kuipers 3f6f35bd95 support_roof_extruder_nr 2015-07-29 14:35:15 +02:00
Tim Kuipers b41288c63d adhesion_extruder_nr 2015-07-29 13:13:18 +02:00
Tim Kuipers 75b13046cf lil changes 2015-07-29 12:20:57 +02:00
Tim Kuipers 2433c8521e logWarning 2015-07-29 12:20:14 +02:00
Tim Kuipers 613e65ecba machine_extruder_count 2015-07-28 15:19:55 +02:00
Tim Kuipers 6a7d9a7c18 machine_extruder_count 2015-07-28 15:18:28 +02:00
Tim Kuipers 6e52f81840 combine infill lines finally bugfixed! 2015-07-28 13:29:13 +02:00
Tim Kuipers 7984932307 bugfix: skirt includes support roofs 2015-07-27 16:18:30 +02:00
Tim Kuipers 871fdc3a01 different wipe tower position, closer to far right corner for UM2 2015-07-27 16:17:52 +02:00
Tim Kuipers 807e734fa4 bugfix: wipe_tower inverse order on first layer 2015-07-27 13:04:30 +02:00
Tim Kuipers b59ebe074d Update README.md 2015-07-27 11:11:59 +02:00
Tim Kuipers 81a3b14999 Merge branch 'master' of https://github.com/Ultimaker/CuraEngine 2015-07-24 17:17:18 +02:00
Tim Kuipers a1a3c079bb settings wipe_tower_dir_outward ::bool 2015-07-24 17:14:14 +02:00
Tim Kuipers 33d5c91227 reverse the print order of the wipe tower skirt to inward 2015-07-24 16:55:28 +02:00
Arjen Hiemstra d43774c664 Merge branch '15.06'
* 15.06: (21 commits)
  bugfix: empty arcus messages
  bugfix & feature: insets support smaller outer wall line width
  Statically link libstdc++ on Linux to prevent issues with newer libstc++
  bugfixes for raft problems: unregistered settings, printZ computed doubly, printZ didn't account for difference in initial slice Z and print Z, initial layer height should be appleid when using raft, wrong (negative) layer comments
  bugfix: extrusion per mm to extrusion mm3 per mm is_volumetric set
  bugfix: speed compensation for stable feedrate also changed the extrusion per mm
  bugfix: speed compensation for stable feedrate also changed the extrusion per mm
  bugfix+refactor: extrusion always per mm3
  bugfix: no support for too low models
  bugfix: no support for too low models
  Also send infill polygon data to the UI, not just oultines
  Also send line width to the UI along with the polygon's points
  Add support for sending layer height and thickness to the UI
  Properly reset the extrusion amount between slicing tasks.
  Properly initialize extrusion_volume_per_mm variable
  bugfix: reset filament at new print
  Add missing <string> include so we can build on MacOSX
  Install the created executable
  bugfix gcode.writeMove(x,y,z) where z didn't get processed. = bug for wireprinting
  Fix support generation by making sure "True" is also recognised as true
  ...
2015-07-24 12:44:00 +02:00
Tim Kuipers 6feb5bbe8c Merge branch 'master' of https://github.com/Ultimaker/CuraEngine 2015-07-24 12:02:31 +02:00
Tim Kuipers ed15bdcc25 bugfixes: progress 2015-07-24 12:01:37 +02:00
Jaime van Kessel 95bbf211ba progress now takes multiple objects for once at a time into account 2015-07-24 11:50:08 +02:00
Jaime van Kessel bb2138b060 bit of refactoring in slices2polygons 2015-07-24 10:55:40 +02:00
Jaime van Kessel debe1c5129 Renamed namespace of protobuff from Cura to cura::proto 2015-07-24 10:06:13 +02:00
Jaime van Kessel 157f0c37f8 fixed one at a time 2015-07-24 09:25:56 +02:00
Jaime van Kessel cac5ee612c Merge branch 'master' of https://github.com/Ultimaker/CuraEngine 2015-07-24 09:05:48 +02:00
Tim Kuipers a931f2f964 bugfix: no more automatic mesh centering (repositioning); now an option: center_object 2015-07-23 18:06:53 +02:00
Tim Kuipers 6450379a1c feature: conical support half implemented 2015-07-23 16:25:24 +02:00
Tim Kuipers 24ece43700 feature: support_extruder_nr_layer_0 2015-07-23 16:19:02 +02:00
Jaime van Kessel ff59738246 Merge branch 'master' of https://github.com/Ultimaker/CuraEngine 2015-07-23 10:19:42 +02:00
Jaime van Kessel b3de3b7643 Changes to make one at a time work (WIP) 2015-07-23 10:19:23 +02:00
Tim Kuipers 1523350501 UM2 gcode now accepts start gcode (though setting default should be empty) 2015-07-23 10:13:58 +02:00
Tim Kuipers 1a5fd99d7e better starting and ending gcode for wireframe 2015-07-23 09:15:54 +02:00
Tim Kuipers 55ee8f687b Merge branch 'master' of https://github.com/Ultimaker/CuraEngine 2015-07-22 16:17:16 +02:00
Tim Kuipers 265adb1a5d bugfix/enhancement: better combine infill lines 2015-07-22 16:17:02 +02:00
Jaime van Kessel 235c561bb5 Renamed modelfile to correct name 2015-07-22 15:49:54 +02:00
Tim Kuipers 1753bd566e merge 2015-07-22 15:36:09 +02:00
Jaime van Kessel 5e8c73a0a2 Moar naming 2015-07-22 15:21:44 +02:00
Jaime van Kessel 5752b358f2 More refactoring 2015-07-22 13:47:16 +02:00
Jaime van Kessel 10d4785659 refactoring 2015-07-22 13:34:24 +02:00
Jaime van Kessel 9beaee7161 Added more documentation 2015-07-22 13:31:02 +02:00
Jaime van Kessel c79e052c17 Refactoring so code adheres to codestyle 2015-07-22 13:18:18 +02:00
Tim Kuipers 5b88fda464 bugfix: removed zigzaggifying infill lines 2015-07-22 12:11:23 +02:00
Tim Kuipers 52cd83bac3 bugfixes: combine infill lines 2015-07-22 12:06:18 +02:00
Tim Kuipers a47adb2114 bugfix: support overlapped with model by half the line width 2015-07-22 10:08:34 +02:00
Tim Kuipers e0001ffa5b enhancement: less copies in polygons.removeDegenerateVerts 2015-07-22 09:31:06 +02:00
Tim Kuipers 58734899d7 enhancement: less copies in polygons.removeDegenerateVerts 2015-07-21 17:24:41 +02:00
Tim Kuipers 60b0f43838 bugfix/feature enhance: better combine infill lines into single line 2015-07-21 16:25:53 +02:00
Tim Kuipers 4bed0e3ad1 bugfix: draft shield disabled skirt; bugfix: infill config was retrieved globally instead of local to the mesh 2015-07-21 13:34:22 +02:00
Tim Kuipers 0e27cbfd4f lil draft shield improvement: more skip_layers 2015-07-20 14:59:32 +02:00
Tim Kuipers 94c29cf0af Merge pull request #222 from electrocbd/bugfix2
Infinite loop in cura::FffPolygonGenerator::processDraftShield
2015-07-20 14:58:09 +02:00
Tim Kuipers 7d1d60b422 bugfix: remove degenerate verts: verts connected to overlapping line segments 2015-07-20 14:37:21 +02:00
Christophe Baribaud 7fca86e27a Keep compatibility with 0.2mm layer height 2015-07-20 14:34:52 +02:00
Christophe Baribaud faeaf2816f Infinite loop in cura::FffPolygonGenerator::processDraftShield 2015-07-20 14:15:18 +02:00
Tim Kuipers 9943279361 Merge branch 'master' of https://github.com/Ultimaker/CuraEngine 2015-07-20 09:11:28 +02:00
Tim Kuipers 58b2d42596 Merge pull request #221 from electrocbd/bugfix1
bugfix: Polygons::splitIntoPartsView_processPolyTreeNode had reference to vector element which could change within the recursive call
2015-07-19 22:42:41 +02:00
Christophe Baribaud c42df2e53e Fix: Polygons::splitIntoPartsView_processPolyTreeNode used a pointer to a
vector which is reallocated, invalidating iterators and pointers
2015-07-19 15:21:06 +02:00
Tim Kuipers 3607a88f0a bugfix: (again) speed and extrusion/mm for combined small moves: for moves smaller than nozzle width, speed should be higher and extrusoin/mm lower 2015-07-15 17:13:42 +02:00
Tim Kuipers 8625365cf0 changed fill_overlap dewfault down; new feature: infill_wipe_dist 2015-07-09 16:53:28 +02:00
Tim Kuipers 941354c740 feat: infill_wipe_dist 2015-07-09 16:48:28 +02:00
Tim Kuipers 13f5ebe9d7 bugfix: empty arcus messages 2015-07-09 14:08:29 +02:00
Tim Kuipers 9ba97a7cd7 reqrote some comments 2015-07-09 11:37:52 +02:00
Tim Kuipers f9bf42f610 feature: draft protection screen 2015-07-08 17:02:30 +02:00
Tim Kuipers ce4a375780 disabled skirt when draft shield is on 2015-07-08 15:55:32 +02:00
Tim Kuipers f0675c88df feature: draft protection screen 2015-07-08 15:20:20 +02:00
Tim Kuipers db787c7cab Merge branch '15.06' of https://github.com/Ultimaker/CuraEngine into 15.06 2015-07-08 13:15:47 +02:00
Tim Kuipers 21a04beb25 bugfix & feature: insets support smaller outer wall line width 2015-07-08 13:15:35 +02:00
Tim Kuipers 0d0dd7292a bugfix & feature: insets support smaller outer wall line width 2015-07-08 13:00:47 +02:00
Tim Kuipers 735f50875e bugfix overlap ocmpensation: removed debug output code 2015-07-07 16:58:28 +02:00
Tim Kuipers f0fd1a654e bugfix for wall overlap compensation (unknown bug origin, but seems fixed by keeping endings separate from normal overlap points). CONTAINS DEBUG output code. 2015-07-07 16:52:35 +02:00
Arjen Hiemstra 1565e979ec Statically link libstdc++ on Linux to prevent issues with newer libstc++
Contributes to Ultimaker/Uranium#42
2015-07-07 12:14:24 +02:00
Tim Kuipers 82532a3ddf fix lil 2015-07-03 14:22:39 +02:00
Tim Kuipers 7075ca34d4 bugfixes for raft problems: unregistered settings, printZ computed doubly, printZ didn't account for difference in initial slice Z and print Z, initial layer height should be appleid when using raft, wrong (negative) layer comments 2015-07-03 13:23:23 +02:00
Tim Kuipers 927395630b bugfixes for raft problems: unregistered settings, printZ computed doubly, printZ didn't account for difference in initial slice Z and print Z, initial layer height should be appleid when using raft, wrong (negative) layer comments 2015-07-02 16:13:32 +02:00
Tim Kuipers 8c9625f578 Merge branch 'master' of https://github.com/Ultimaker/CuraEngine 2015-07-01 17:19:26 +02:00
Tim Kuipers 7c4064aa5f travel_compensate_overlapping_walls_enabled fixed 2015-07-01 17:19:16 +02:00
Tim Kuipers 6d82284545 Update README.md 2015-07-01 10:34:23 +02:00
Tim Kuipers fe512222e5 bugfix: extrusion per mm to extrusion mm3 per mm is_volumetric set 2015-06-30 17:20:02 +02:00
Tim Kuipers 79d164b2d4 bugfix: extrusion per mm to extrusion mm3 per mm is_volumetric set 2015-06-30 17:18:00 +02:00
Tim Kuipers a18cfd9af1 halfway bugfix+refactor: extrusion per mm to extrusion mm3 per mm 2015-06-30 16:16:02 +02:00
Tim Kuipers 7469a48449 Merge branch 'master' of https://github.com/Ultimaker/CuraEngine 2015-06-30 15:38:55 +02:00
Tim Kuipers 9c8bac7a99 halfway bugfix+refactor: extrusion per mm to extrusion mm3 per mm 2015-06-30 15:38:53 +02:00
Tim Kuipers 3cfbc20d75 bugfix: speed compensation for stable feedrate also changed the extrusion per mm 2015-06-30 14:48:59 +02:00
Tim Kuipers 9baaa93159 bugfix: speed compensation for stable feedrate also changed the extrusion per mm 2015-06-30 14:47:40 +02:00
Tim Kuipers 9b92c42947 bugfix: speed compensation for stable feedrate also changed the extrusion per mm 2015-06-30 14:46:26 +02:00
Tim Kuipers fcaa7d71b7 bugfix: speed compensation for stable feedrate also changed the extrusion per mm 2015-06-30 14:44:39 +02:00
Tim Kuipers 423516ddd9 bugfix+refactor: extrusion always per mm3 2015-06-30 14:34:29 +02:00
Tim Kuipers 0a77aaa385 overlap compensation 2015-06-30 09:31:57 +02:00
Roy Spliet a54e70e48f CMake: Add packaging definition
Signed-off-by: Roy Spliet <r.spliet@ultimaker.com>
2015-06-26 13:57:19 +02:00
daid d3e41f3ce2 Add missing rapidjson license. 2015-06-26 11:13:47 +02:00
Tim Kuipers a9b4aa7640 bugfix: no more removal of last point (caused by overwriting each point by the last) 2015-06-24 17:15:26 +02:00
Tim Kuipers 95ff26940e bugfix: disabled overlap compensation due to temporary bug 2015-06-24 16:33:54 +02:00
Tim Kuipers e5f87bcbc7 bugfixes: hasSetting removed due to new setting system introduced months ago, mesh positioning bugfix 2015-06-24 16:22:30 +02:00
Tim Kuipers 210636e205 lil 2015-06-24 15:32:27 +02:00
Tim Kuipers 028c8c6e42 no more debug out bs 2015-06-24 15:00:25 +02:00
Tim Kuipers 73f5691651 bugfix: nozzle offset 2015-06-24 15:00:09 +02:00
Tim Kuipers afc3088427 bugfix: no support for too low models 2015-06-24 14:28:10 +02:00
Tim Kuipers f1ac6c05b1 bugfix: no support for too low models 2015-06-24 14:27:49 +02:00
Tim Kuipers ddc2c1e574 dgf 2015-06-24 14:27:26 +02:00
Tim Kuipers fcbcf380ae Merge branch 'master' of https://github.com/Ultimaker/CuraEngine 2015-06-24 13:14:25 +02:00
Tim Kuipers eccda61b55 bugfix: machine_extruder_offset >> machine_nozzle_offset 2015-06-24 13:14:15 +02:00
Tim Kuipers 0f8b52d1a0 overlap compensation halfway 2015-06-24 13:12:17 +02:00
Tim Kuipers 35373a5b1a overlap compensation half way : location based 2015-06-23 13:45:38 +02:00
Tim Kuipers 094d0e84a2 bugfix: no support for too low models 2015-06-23 10:11:09 +02:00
Tim Kuipers a5beedf4f6 bugfix: no support for too low models 2015-06-23 10:07:47 +02:00
Tim Kuipers a77f0bf728 first wall overlap compensation approximation (links a point to multiple overlaps to account for threeway overlaps) 2015-06-22 12:22:28 +02:00
Ghostkeeper 8a75b638b7 Restore documentation output directory
The output directory had to be changed back to docs for the automatic
generation of documentation.
2015-06-19 10:24:24 +02:00
Ghostkeeper 0815a834d8 Emptied the documentation output directory
This output directory needs to be empty in order to automatically
publish the documentation.
2015-06-18 16:12:19 +02:00
Tim Kuipers 93c9864f17 split remove_overlapping_perimeters into outer and other 2015-06-18 13:25:05 +02:00
Tim Kuipers 2444667a70 lil 2015-06-18 10:06:48 +02:00
Tim Kuipers 0ec956c653 enhanced support roof direction 2015-06-17 15:03:28 +02:00
Tim Kuipers ccd1c44315 stop wipe tower after last neccesary switch (+bugfixes) 2015-06-17 14:56:00 +02:00
Tim Kuipers bed85c7e68 stop wipe tower after last neccesary switch 2015-06-16 17:26:54 +02:00
Tim Kuipers 4e40b2bc09 support roof lil stuff 2015-06-16 14:42:27 +02:00
Tim Kuipers 6fbe9c7de8 bugfix: setting typo 2015-06-16 12:36:35 +02:00
Arjen Hiemstra d965f1b7e5 Also send infill polygon data to the UI, not just oultines
Contributes to Ultimaker/Cura#52
2015-06-16 12:35:50 +02:00
Arjen Hiemstra 172722c63b Also send line width to the UI along with the polygon's points
Contributes to Ultimaker/Cura#52
2015-06-16 12:34:49 +02:00
Arjen Hiemstra 702564f5c6 Add support for sending layer height and thickness to the UI
Contributes to Ultimaker/Cura#52
2015-06-16 12:30:39 +02:00
Tim Kuipers 5b70a57700 documenting AABB 2015-06-16 12:11:33 +02:00
Tim Kuipers 1ce42b6b93 lil 2015-06-16 12:07:20 +02:00
Tim Kuipers e5b79ea847 lil 2015-06-16 12:06:58 +02:00
Tim Kuipers 70168cde07 introduced AABB (axis aligned bounding box) and cura'd a related bug 2015-06-16 12:04:34 +02:00
Tim Kuipers 7dad3d5018 different command line execution example 2015-06-16 11:25:02 +02:00
Tim Kuipers 87fbaf51f9 different command line execution example 2015-06-16 11:23:10 +02:00
Tim Kuipers 5cf401cde7 Merge branch 'master' of https://github.com/Ultimaker/CuraEngine 2015-06-16 11:18:31 +02:00
Tim Kuipers 136aea0c15 support roof settings 2015-06-16 11:18:18 +02:00
Tim Kuipers 8e43531e10 more lenient settings handling so that you can load multiple json files after eachother 2015-06-16 11:16:36 +02:00
Arjen Hiemstra 329d85a9aa Properly reset the extrusion amount between slicing tasks.
This fixes an issue where extrusion amount would be ridiculously high
since it used the old value for a new slicing task.
2015-06-15 13:36:40 +02:00
Ghostkeeper 7ac77ba24b Readme correction: There is an external dependency
The external dependency is libArcus. A reference to libArcus is added in
the place where it said there are no external dependencies.
2015-06-12 13:45:25 +02:00
Tim Kuipers 1406c8f2ea magic_polygon mode => magic_mesh_surface_mode 2015-06-11 14:32:55 +02:00
Tim Kuipers c0715fd490 first approximation support roofs 2015-06-11 13:57:23 +02:00
Tim Kuipers 267e0b1fa9 LARGE REFACTOR: all variables which eventually get values from double settings have been changed from int to double 2015-06-10 11:19:37 +02:00
Tim Kuipers dcf56c5a8e new feature: alternate skin rotation (45 degrees for every two pairs of layers 2015-06-09 17:24:47 +02:00
Tim Kuipers bf23ca38ba bugfix: support line width, Fixes daid/Cura#1274 2015-06-09 14:58:05 +02:00
Tim Kuipers b851be6a06 progress takes care of timeKeeper 2015-06-09 14:31:46 +02:00
Tim Kuipers 84b3176ac3 progress docs and sendProgressStage 2015-06-09 13:41:33 +02:00
Tim Kuipers b9f8325534 better progress calculation 2015-06-09 13:09:30 +02:00
Tim Kuipers 9fa902ad6d license correction 2015-06-09 13:09:12 +02:00
Tim Kuipers 68888fc0b7 license correction 2015-06-09 13:07:41 +02:00
Tim Kuipers 136e199225 lil 2015-06-09 13:06:43 +02:00
Arjen Hiemstra 0a31584760 Properly initialize extrusion_volume_per_mm variable
This fixes issues with volumetric mode.

Contributes to Asana issue 36101603778517
2015-06-09 11:13:53 +02:00
Tim Kuipers 295e51309f bugfix: incorrect model translation upward 2015-06-08 16:57:54 +02:00
Tim Kuipers 5f09352a24 bugfix: retract on very first move, causing the head to move to an impossible position 2015-06-08 15:24:35 +02:00
Tim Kuipers 94faff843f Merge branch 'master' of https://github.com/Ultimaker/CuraEngine 2015-06-08 13:33:53 +02:00
Tim Kuipers 2efce629f7 coasting finished + settings 2015-06-08 13:24:09 +02:00
Tim Kuipers 6964c7122b removed move_inside_comb_boundary, since that is already dont by the combing 2015-06-08 10:04:42 +02:00
Tim Kuipers 6b97779ac8 Update README.md 2015-06-08 09:23:50 +02:00
Tim Kuipers 5d9c64a140 differentiate between move-coasting and retract-coasting 2015-06-05 12:41:19 +02:00
Tim Kuipers 5ca046fec2 differentiate between move-coasting and retract-coasting 2015-06-05 12:40:31 +02:00
Tim Kuipers 5657577938 moved coasting to gcodePlanner.writeGcode() and introduced coasting priming 2015-06-05 12:14:42 +02:00
Tim Kuipers 224fec0b79 first coasting code part and gcodeLayer.writeGcode refactors 2015-06-03 15:44:36 +02:00
Tim Kuipers ae2b67ef69 lil 2015-06-03 13:05:38 +02:00
Tim Kuipers 3b8ad5e55c added setting travel_avoid_other_parts 2015-06-03 13:04:00 +02:00
Tim Kuipers abd2c586db moved fdmPrinter.json to the frontend (merged) 2015-06-02 17:09:35 +02:00
Tim Kuipers 0a8b508b4c lil 2015-06-02 11:45:30 +02:00
Tim Kuipers df97f36315 better retraction handling 2015-06-02 11:43:10 +02:00
Tim Kuipers cc3ce8ae6b add setting travel_avoid_distance 2015-06-02 11:32:29 +02:00
Tim Kuipers ba2f47aa67 Merge branch 'masterhou-master-hyt' 2015-06-01 17:10:37 +02:00
Tim Kuipers e516682744 corrected wrong initialization in polygon.cpp 2015-06-01 16:07:25 +02:00
Tim Kuipers f43f4285a8 Merge branch 'master-hyt' of https://github.com/masterhou/CuraEngine into masterhou-master-hyt 2015-06-01 15:59:15 +02:00
Tim Kuipers 99c756aa90 lil 2015-06-01 14:15:45 +02:00
Tim Kuipers a8a2d69a5f better comb inside offset, don't use comb path when zhop is used. 2015-06-01 12:32:45 +02:00
Tim Kuipers f7ac889bb4 more retractions between support (but not always) 2015-06-01 11:26:05 +02:00
Tim Kuipers a326e73e4a cleaning up combing, explanations, comments 2015-06-01 11:23:49 +02:00
Thomas Hou 2796103a2b some optimization
1.load stl
2.use std::unordered_map instead of std::map
3.slicer, polygon close, find face by segment idx.
4.insert <k,v> fater than [k]=v;
2015-05-29 16:39:16 +08:00
Tim Kuipers 14c4ac55f1 Merge branch 'combingOverhaul' 2015-05-28 16:02:55 +02:00
Tim Kuipers 831b9d94f8 combing cleanup etc 2015-05-28 15:59:55 +02:00
Tim Kuipers 5fa793ece7 lil 2015-05-28 14:20:55 +02:00
Tim Kuipers 4065e6f7e8 refactor combing: no more force retraction, no more boundary with extra offset 2015-05-28 14:13:05 +02:00
Tim Kuipers 7ff00dfbb0 combing seems to be working 2015-05-26 17:04:26 +02:00
Tim Kuipers 84909e2e77 Merge pull request #211 from foosel/fix/usage_summary
Usage summary should match actual usage
2015-05-26 15:25:28 +02:00
Gina Häußge 9d75cdf0f7 Usage summary should match actual usage
Removed obsolete `-m` and `-c` and added missing
`--connect`, `-j` and `-p`.
2015-05-26 15:00:06 +02:00
Tim Kuipers 01f1568dda bugfix: reset filament at new print 2015-05-26 12:33:13 +02:00
Tim Kuipers c0c842649f lil commit 2015-05-26 12:26:42 +02:00
Tim Kuipers e8d117d62f UltiGCode starting gcode fallback option when not using command sockets 2015-05-26 11:50:24 +02:00
Tim Kuipers 87ae0dc870 bugfix for boundary point with offset for outside combing 2015-05-26 11:44:27 +02:00
Tim Kuipers e26ee1a113 debugging, testing 2015-05-26 11:12:08 +02:00
Tim Kuipers 9d31a525c9 UltiGCode starting gcode fallback option when not using command sockets 2015-05-26 10:56:26 +02:00
Tim Kuipers ffb08f9f8d more cdombing overhaul (debug state) 2015-05-26 10:46:23 +02:00
Tim Kuipers 294dec007a Merge pull request #210 from osbornm/patch-1
Update README to display build steps as list
2015-05-26 10:32:01 +02:00
Matthew Osborn 93a19422e8 Update README to display build steps as list
This way the steps show up as a list and stand out so it's easier to see.
2015-05-25 22:37:26 -07:00
Tim Kuipers c44adab86d combing cleanup 2015-05-19 12:31:39 +02:00
Tim Kuipers 7bb5cbe98e first combing overhaul commit which seems to work 2015-05-19 10:52:04 +02:00
Arjen Hiemstra 883b0c2efc Add missing <string> include so we can build on MacOSX
Contributes to Ultimaker/Uranium#41
2015-05-18 13:55:34 +02:00
Arjen Hiemstra 57c91c35b0 Install the created executable
This makes it easier to build a combined setup of all things in
Cura.

Contributes to Ultimaker/Uranium#41
2015-05-18 13:54:02 +02:00
Tim Kuipers 0b0db9f864 comb boundary = whole layer 2015-05-18 13:33:03 +02:00
Tim Kuipers 00a2a2a107 bugfix gcode.writeMove(x,y,z) where z didn't get processed. = bug for wireprinting 2015-05-18 11:13:14 +02:00
Arjen Hiemstra 64ddaf2ff5 Fix support generation by making sure "True" is also recognised as true 2015-05-18 11:11:59 +02:00
Tim Kuipers a901e88aaa bugfix gcode.writeMove(x,y,z) where z didn't get processed. = bug for wireprinting 2015-05-18 10:32:39 +02:00
Tim Kuipers fe03259704 more refactoring 2015-05-18 09:25:01 +02:00
Arjen Hiemstra eb164c8a0e Fix support generation by making sure "True" is also recognised as true 2015-05-15 17:48:43 +02:00
Tim Kuipers cf209a157b first working comb 2015-05-15 13:30:43 +02:00
Tim Kuipers 0f547ae354 test cleanup 2015-05-15 13:30:19 +02:00
Tim Kuipers 2ebfbe837d includes cleanup 2015-05-15 13:29:58 +02:00
Tim Kuipers af87a00eaa bugfixes splitIntoPartsView 2015-05-15 13:27:28 +02:00
Tim Kuipers 09543636c7 more combing refactor 2015-05-13 17:08:09 +02:00
Tim Kuipers f5a56a5048 some new polygon functionality and linear algebra 2015-05-13 17:07:54 +02:00
Tim Kuipers 16185bd88c more combing refactor 2015-05-13 09:18:36 +02:00
Tim Kuipers 47479a9fd5 further combing refactoring 2015-05-12 17:24:49 +02:00
Tim Kuipers fce31b0c32 Merge branch 'master' into combingOverhaul 2015-05-12 15:29:03 +02:00
Tim Kuipers d44c68a28b further crystallized addMeshLayerToGcode 2015-05-12 15:18:21 +02:00
Tim Kuipers 5f793943f2 small refactor 2015-05-12 13:04:09 +02:00
Tim Kuipers 3d81f84c0f totally broke apart the writeGcode function 2015-05-12 12:48:10 +02:00
Tim Kuipers 9f59447a81 fff classes extend settingbase again, instead of having a settings field 2015-05-12 11:39:12 +02:00
Tim Kuipers 67c9b3dd23 totally broke apart what was formerly known as fffProcessor::prepareModel(.) 2015-05-11 14:50:46 +02:00
Tim Kuipers f1028b55a2 refactored and commented FffPolygonGenerator 2015-05-11 14:20:35 +02:00
Tim Kuipers 4cb11122dc renamed FffAreagenerator to FffPolygonGenerator 2015-05-11 14:01:34 +02:00
Tim Kuipers 58438bf56e renamed FffAreagenerator to FffPolygonGenerator 2015-05-11 13:59:44 +02:00
Tim Kuipers e93ba3d37f refactored some FffAreaGenerator functionality 2015-05-11 13:54:37 +02:00
Tim Kuipers 9566e60037 imports cleanup 2015-05-11 13:39:34 +02:00
Tim Kuipers b0b06635ac split off FffAreaGenerator from fffProcessor 2015-05-11 13:36:50 +02:00
Tim Kuipers 6dfacb7d2c rename GcodeWriter to FffGcodeWriter 2015-05-11 13:07:29 +02:00
Tim Kuipers f1774665df moved writeGcode to cpp file 2015-05-11 12:27:15 +02:00
Tim Kuipers 45c8439446 cleaned up some imports 2015-05-11 12:13:53 +02:00
Tim Kuipers 1d0fded682 split fffProcessor into fffProcessor and GcodeWriter 2015-05-11 12:03:07 +02:00
Tim Kuipers 31a81c5476 forgotten polygon.cpp 2015-05-11 09:27:52 +02:00
Tim Kuipers 229d3b1a2f halfway refactoring combing 2015-05-11 09:21:01 +02:00
daid 61c4ffd982 test does not build on windows, remove it for now so we can build a release. 2015-05-07 16:39:57 +02:00
Tim Kuipers 796ced3508 Merge branch 'master' of https://github.com/Ultimaker/CuraEngine 2015-05-07 11:28:36 +02:00
daid c91137cc03 Merge branch '15.06' 2015-05-06 09:24:24 +02:00
daid 6df992580a Fix #193 2015-05-06 09:24:14 +02:00
Tim Kuipers d061420750 improved Comb::move inside 2015-05-04 17:23:03 +02:00
Tim Kuipers 50ef87d41f combing debug 2015-05-04 16:39:39 +02:00
Tim Kuipers c4952dd28f removed 'using default' msg 2015-05-04 16:39:22 +02:00
Tim Kuipers 6c5c5c2e34 removed comment 2015-05-04 16:38:24 +02:00
Tim Kuipers 1520e010e7 removed unneccesary import 2015-05-04 16:38:04 +02:00
Tim Kuipers 30bd8b5c67 support everywhere as default 2015-05-04 11:00:54 +02:00
Tim Kuipers 8cc54c60de refactored combing: one combing path per boundary polygon, needs more cleaning up and testing 2015-05-01 16:20:18 +02:00
Tim Kuipers a4a5e22b50 refactored combing more 2015-05-01 15:12:49 +02:00
Tim Kuipers 4529585acb made outlines into PolygonPart 2015-05-01 11:56:14 +02:00
Tim Kuipers d1bc5f8002 moved multiVolumeOverlap code from processSliceData to prepareModel, cause it should be done before layer parts are generated 2015-05-01 11:47:37 +02:00
Tim Kuipers ab68ee508e removed remove-first-empty-layers code which was old and at the wrong place 2015-05-01 11:21:36 +02:00
Tim Kuipers db7eb35e34 introduced a new class to signify that a Polygons object is a single area: PolygonsPart 2015-05-01 10:34:32 +02:00
Tim Kuipers 216ab79521 bit more explanation findSmallestConnection 2015-05-01 09:48:48 +02:00
Tim Kuipers 2a74c39642 removed slow findSmallestConnection 2015-05-01 09:45:37 +02:00
Tim Kuipers eeaa53c118 lil comments 2015-05-01 09:43:11 +02:00
Tim Kuipers effff44843 commenting and refactoring comb.h &.cpp 2015-04-30 17:12:34 +02:00
Tim Kuipers 99ea16e251 refactoring and commenting and correcting grammar ((TM) grammar nazi) 2015-04-30 14:54:19 +02:00
Tim Kuipers 574a89ad93 refactoring and commenting combing 2015-04-30 12:34:40 +02:00
Arjen Hiemstra f4af9ec780 Fix merge issues 2015-04-30 11:01:45 +02:00
Arjen Hiemstra 81dc71a2de Merge branch 'PinkUnicorn'
* PinkUnicorn: (286 commits)
  some lil testing code for findSmallestConnection
  findClosestConnection between two polygons
  Account for volumatric extrusion.
  made the comb boundary larger, so that (barely) connected parts still use the comb boundary
  moved to polygonUtils: findClosest to polygon etc.
  setting fill_perimeter_gaps
  Do not write temperature commands for UltiGCode.
  bugfix: no abs(.) in centerOfMass!
  operator == already exported by Clipper!
  lil rewrite
  deleted my buggy polygon.inside() function
  debugged my polygon.inside a bit and added the one from gsmith-to https://github.com/Ultimaker/CuraEngine/pull/189
  better polygon.inside testing
  Fix the machine offset for PU.
  included BucketGrid3D in pathOrderOptimizer
  lil bugifxes for bucketGrid2D
  2D hash grid class for finding nearby items
  made zigzags the default suppoirt type
  Properly rename some dual extrusion settings.
  bugfix center of mass when center.x < 0 etc.
  ...
2015-04-30 10:45:33 +02:00
Tim Kuipers 9f36330fe6 some lil testing code for findSmallestConnection 2015-04-30 10:03:24 +02:00
Tim Kuipers f73094179e Merge branch 'PinkUnicorn' of https://github.com/Ultimaker/CuraEngine into PinkUnicorn 2015-04-30 09:26:11 +02:00
Tim Kuipers a430281b46 findClosestConnection between two polygons 2015-04-30 09:25:58 +02:00
daid 57820afdfa Account for volumatric extrusion. 2015-04-29 18:00:40 +02:00
Tim Kuipers 8ed7d6e4d5 Merge branch 'PinkUnicorn' of https://github.com/Ultimaker/CuraEngine into PinkUnicorn 2015-04-29 16:05:23 +02:00
Tim Kuipers c23701d7f1 made the comb boundary larger, so that (barely) connected parts still use the comb boundary 2015-04-29 15:12:45 +02:00
Tim Kuipers 8964454bf4 moved to polygonUtils: findClosest to polygon etc. 2015-04-29 15:12:03 +02:00
Tim Kuipers 153370bbcb setting fill_perimeter_gaps 2015-04-29 15:10:46 +02:00
daid ff28da5bde Merge branch 'PinkUnicorn' of github.com:Ultimaker/CuraEngine into PinkUnicorn 2015-04-29 14:48:31 +02:00
daid 2ea7a8724a Do not write temperature commands for UltiGCode. 2015-04-29 14:48:21 +02:00
Tim Kuipers d073dda5c4 bugfix: no abs(.) in centerOfMass! 2015-04-29 12:56:06 +02:00
Tim Kuipers 93be1b8d63 operator == already exported by Clipper! 2015-04-29 12:54:02 +02:00
Tim Kuipers 0991624234 lil rewrite 2015-04-29 12:19:36 +02:00
Tim Kuipers bc28971f10 Merge branch 'PinkUnicorn' of https://github.com/Ultimaker/CuraEngine into PinkUnicorn 2015-04-29 12:17:41 +02:00
Tim Kuipers c98b6ba8a8 deleted my buggy polygon.inside() function 2015-04-29 12:17:28 +02:00
Tim Kuipers 600eed61fc debugged my polygon.inside a bit and added the one from gsmith-to https://github.com/Ultimaker/CuraEngine/pull/189 2015-04-29 12:16:51 +02:00
Tim Kuipers 0088c2e6ca better polygon.inside testing 2015-04-29 12:15:23 +02:00
daid cdf7628287 Fix the machine offset for PU. 2015-04-29 12:11:27 +02:00
Tim Kuipers 7b7e9eec24 Merge branch 'PinkUnicorn' of https://github.com/Ultimaker/CuraEngine into PinkUnicorn 2015-04-29 11:53:51 +02:00
Tim Kuipers 326ba11c87 included BucketGrid3D in pathOrderOptimizer 2015-04-28 17:30:31 +02:00
Tim Kuipers eee41a6aee lil bugifxes for bucketGrid2D 2015-04-28 15:46:35 +02:00
Tim Kuipers 20fa95def8 2D hash grid class for finding nearby items 2015-04-28 14:25:22 +02:00
Tim Kuipers 43c3b11253 made zigzags the default suppoirt type 2015-04-28 14:24:23 +02:00
daid 7c708c1072 Merge branch 'PinkUnicorn' of github.com:Ultimaker/CuraEngine into PinkUnicorn 2015-04-28 11:50:48 +02:00
daid 33b287000c Properly rename some dual extrusion settings. 2015-04-28 11:50:39 +02:00
Tim Kuipers 97ed92d785 Merge branch 'PinkUnicorn' of https://github.com/Ultimaker/CuraEngine into PinkUnicorn 2015-04-28 11:39:46 +02:00
Tim Kuipers 218a028dd6 bugfix center of mass when center.x < 0 etc. 2015-04-28 11:33:40 +02:00
daid a53977e49c Merge branch 'PinkUnicorn' of github.com:Ultimaker/CuraEngine into PinkUnicorn 2015-04-28 11:15:24 +02:00
daid 3c718af85e Only offset the model if the called filled in the proper settings. 2015-04-28 11:13:56 +02:00
Tim Kuipers ae3c113ca0 corrected default top/bottom thickness to what should result from inherit function at defaults 2015-04-28 11:11:09 +02:00
Tim Kuipers b3f3135157 test file for quick n dirty tests 2015-04-28 10:48:17 +02:00
Tim Kuipers 3d8e1d39d7 test file for quick n dirty tests 2015-04-28 10:45:02 +02:00
Tim Kuipers a7335a5caa better checking of whether we are inside a polygon 2015-04-28 10:41:41 +02:00
daid a2f88584bf Link pthread on unix oses. (Should be handled better, as protobuf actually needs pthreads, not the CuraEngine. But this works for now) 2015-04-28 09:49:51 +02:00
Tim Kuipers 61c3de631e put cpp files in namespace (for consistency) 2015-04-28 09:47:50 +02:00
Tim Kuipers 2aa72aa0c4 changed default initial layer thickness to 0.2mm 2015-04-28 09:27:29 +02:00
Tim Kuipers c2c7e4dac3 Merge branch 'PinkUnicorn' of https://github.com/Ultimaker/CuraEngine into PinkUnicorn 2015-04-24 17:24:26 +02:00
Tim Kuipers 626eed9ecb retraction limiting per extruded material 2015-04-24 17:24:14 +02:00
Tim Kuipers e1420f661d added setting alternate_extra_perimeter 2015-04-24 16:25:40 +02:00
Tim Kuipers e8faa99a46 better terminal run commands 2015-04-24 16:24:33 +02:00
daid 8f2fe55f54 Update code_conventions.md 2015-04-24 13:40:45 +02:00
daid e587cf0bee Make code bit clearer. 2015-04-24 12:32:22 +02:00
daid 1fb0ed5c5a Merge branch 'PinkUnicorn' of github.com:Ultimaker/CuraEngine into PinkUnicorn
Conflicts:
	src/skin.cpp
2015-04-24 12:14:15 +02:00
daid 5163caed25 Simplyfly the sparse infill generation code. 2015-04-24 12:10:39 +02:00
Tim Kuipers bd90859055 bugfix: perimeterGaps were also used when skinPart was bridged and didn't have perimeters! 2015-04-24 12:01:04 +02:00
Tim Kuipers 50cdb76249 split skins into parts as skin_parts in the sliceDataStorage.SliceLayerPart 2015-04-24 10:46:53 +02:00
daid 36e7e2c4f4 Merge branch 'PinkUnicorn' of github.com:Ultimaker/CuraEngine into PinkUnicorn 2015-04-24 10:06:04 +02:00
daid c66ca18e1f Temp fix for the skin multiple line export bug. 2015-04-24 10:05:54 +02:00
Tim Kuipers f68a82eca4 Merge branch 'PinkUnicorn' of https://github.com/Ultimaker/CuraEngine into PinkUnicorn 2015-04-24 09:45:29 +02:00
Tim Kuipers 24f74a733b moved perimeterGap generation into skin.cpp; lil skirt change; commented out extra perimeter at uneven layers 2015-04-24 09:45:22 +02:00
daid ae545a9ee9 Allow json file from commandline. 2015-04-23 14:51:23 +02:00
daid 45a4f2f28f Merge branch 'PinkUnicorn' of github.com:Ultimaker/CuraEngine into PinkUnicorn 2015-04-23 13:54:43 +02:00
daid b533629835 Somehow the tower_roof size becomes 0 sometimes. 2015-04-23 13:54:35 +02:00
Tim Kuipers 282442c00c setting: support bottom stair distance; also some description enhancements to support-type 2015-04-23 12:33:31 +02:00
Tim Kuipers 1a014c9b36 example run from terminal in README 2015-04-23 12:20:39 +02:00
Tim Kuipers 66385ed4bd example run from terminal in README 2015-04-23 12:10:16 +02:00
Tim Kuipers f6013a8683 quick hack for added mesh_postion_x y z to setting registry 2015-04-23 11:58:58 +02:00
Tim Kuipers 3b798fb593 load settings JSON before parsing command line arguments! 2015-04-23 11:43:44 +02:00
daid ab36feefbe Fix flavor name parsing. 2015-04-23 11:27:11 +02:00
Tim Kuipers a509e6af7e added cool_min_layer_time_fan_speed_max, skin_outline_count, xy_offset to settings 2015-04-23 11:18:21 +02:00
Tim Kuipers 607989c28e bugfix: perimeter gaps filled didnt skip topmost layer 2015-04-23 10:44:18 +02:00
Tim Kuipers a31c855141 Merge branch 'PinkUnicorn' of https://github.com/Ultimaker/CuraEngine into PinkUnicorn 2015-04-23 10:22:10 +02:00
daid 6a288763b1 travel and extrude time where uninitialized. 2015-04-23 10:22:00 +02:00
Tim Kuipers 16d960d5b7 set machine defaults to UM2 (temporarily) 2015-04-23 10:21:52 +02:00
Tim Kuipers ed659ea663 Merge branch 'PinkUnicorn' of https://github.com/Ultimaker/CuraEngine into PinkUnicorn 2015-04-23 10:20:22 +02:00
Tim Kuipers 71af3e1548 machine settings added 2015-04-23 10:20:07 +02:00
Tim Kuipers 999f90cc00 remark on skin+sparse computation 2015-04-23 10:19:47 +02:00
daid 51214f9dfd Disable error catching in debug. 2015-04-23 09:52:57 +02:00
daid aaa871157b Stop slicing if there are no layers (prevents crashes and lots of checks later on) 2015-04-23 09:15:57 +02:00
Tim Kuipers 488d74c950 commenting skirt, skin, infill 2015-04-22 16:42:46 +02:00
Tim Kuipers bf23980e57 fixing maxRetractions setting 2015-04-22 16:13:48 +02:00
Tim Kuipers b175265385 commenting wireprinting 2015-04-22 16:13:19 +02:00
Tim Kuipers 8403514604 removed bug in perimeterGaps infill, implemented extra perimeter at uneven layers (is always on! for now); implemented max retractions per x amont of material (not tested) 2015-04-22 15:02:35 +02:00
Tim Kuipers 9e1a2c674e Merge branch 'PinkUnicorn' of https://github.com/Ultimaker/CuraEngine into PinkUnicorn 2015-04-22 14:16:57 +02:00
daid cbe36a41c3 Fix support selection handling. 2015-04-22 14:05:19 +02:00
Tim Kuipers 14e7397a53 Merge branch 'PinkUnicorn' of https://github.com/Ultimaker/CuraEngine into PinkUnicorn 2015-04-22 14:02:02 +02:00
daid abbda6cd88 Add sparse infill line distance so sparse infill works again. 2015-04-22 13:52:33 +02:00
Tim Kuipers 44411a45c7 Merge branch 'PinkUnicorn' of https://github.com/Ultimaker/CuraEngine into PinkUnicorn 2015-04-22 13:51:52 +02:00
Tim Kuipers 79b2b36ecf start of implementation of max n retractions over a given part of filament 2015-04-22 13:51:48 +02:00
daid 7a05419def Add a bunch of missing settings, improve brim/skirt/raft handling in engine. 2015-04-22 13:46:04 +02:00
daid 8423d2ab6c Converted most of the settings. Some still missing in json. some logic is still missing (when raft/brim. When support or not) 2015-04-22 12:41:12 +02:00
daid 44ab7dd0cd Merge branch 'PinkUnicorn' of github.com:Ultimaker/CuraEngine into PinkUnicorn 2015-04-22 12:17:49 +02:00
daid e6f4851d00 More setting renames. 2015-04-22 12:17:42 +02:00
daid e3d89e9fae Fix another bunch of settings. Split the retraction speed into 2 optional settings. 2015-04-22 12:12:42 +02:00
Tim Kuipers 4623962a11 There is no spoon 2015-04-22 12:02:57 +02:00
daid 3c37901918 More setting renames. 2015-04-22 11:48:41 +02:00
Tim Kuipers b763469114 Merge branch 'PinkUnicorn' of https://github.com/Ultimaker/CuraEngine into PinkUnicorn 2015-04-22 11:35:01 +02:00
Tim Kuipers 33e68d7534 skirt convex hull approximation 2015-04-22 11:34:57 +02:00
daid 903d0b3260 Instead of crashing, report back that we failed to open the json file. 2015-04-22 11:34:41 +02:00
daid 52ca544328 Merge branch 'PinkUnicorn' of github.com:Ultimaker/CuraEngine into PinkUnicorn 2015-04-22 11:22:40 +02:00
daid 80ada66e91 Start with renaming settings for the new setting registry. 2015-04-22 11:22:34 +02:00
daid 4e9bc9c955 add fdmprinter.json. 2015-04-22 11:22:08 +02:00
Tim Kuipers d406cd3fd1 import got lost 2015-04-22 10:47:51 +02:00
Tim Kuipers 0e375ca376 import typo 2015-04-22 10:28:25 +02:00
Tim Kuipers 6c4d758cd9 file convention changes 2015-04-22 10:26:56 +02:00
Tim Kuipers 1cd7c82c03 import typo 2015-04-22 10:26:26 +02:00
Tim Kuipers 641dd33d74 fill perimeter gaps only on topmost or bottom most layers 2015-04-22 10:26:01 +02:00
daid e48e4dea7b Start with renaming settings for the new setting registry. 2015-04-22 10:21:21 +02:00
daid 0aa163d84d Merge branch 'PinkUnicorn' of github.com:Ultimaker/CuraEngine into PinkUnicorn 2015-04-21 16:48:05 +02:00
daid c2a233db51 add rapidjason. 2015-04-21 16:47:56 +02:00
Tim Kuipers e90d3008c2 Merge branch 'PinkUnicorn' of https://github.com/Ultimaker/CuraEngine into PinkUnicorn 2015-04-21 16:44:57 +02:00
Tim Kuipers 59879ba38f whoops accidentally made global function into class function 2015-04-21 16:43:58 +02:00
daid 266e280860 Merge branch 'PinkUnicorn' of github.com:Ultimaker/CuraEngine into PinkUnicorn 2015-04-21 16:38:11 +02:00
daid 6c489217f5 Start of updating setting names. 2015-04-21 16:38:07 +02:00
daid d4bae3c377 Small fix for the setting registy, list should be used instead of vector, as list does not move the memory around causing pointers to be invalid. 2015-04-21 16:20:16 +02:00
Tim Kuipers 15cf1bffc8 some refactoring and extra commenting 2015-04-21 16:16:18 +02:00
Tim Kuipers bb7d6f4cdc some refactoring and extra commenting 2015-04-21 16:14:44 +02:00
Tim Kuipers 1936cbb781 code conventions 2015-04-21 16:13:55 +02:00
daid 55f4ad68a9 Refactor how the settings are read and stored with the registry. This will need the fdmprinter.json file from PluggableUnicorn. Note: Currently this will break intigration. 2015-04-21 15:57:51 +02:00
Tim Kuipers a45f936366 some refactoring and cleaning up of bad practices 2015-04-21 13:10:42 +02:00
Tim Kuipers dcef0205b2 Merge branch 'PinkUnicorn' of https://github.com/Ultimaker/CuraEngine into PinkUnicorn 2015-04-21 11:42:54 +02:00
daid 61976be9c1 Fix compile issue. 2015-04-21 11:42:37 +02:00
Tim Kuipers fd5f33570d Bugfix: ancient header protection was missing 2015-04-21 11:10:52 +02:00
Tim Kuipers ff568d0be2 Merge branch 'PinkUnicorn' of https://github.com/Ultimaker/CuraEngine into PinkUnicorn 2015-04-21 11:04:44 +02:00
daid b29d71b2cc Fix crash when IP with no port is given on connect. 2015-04-21 11:03:08 +02:00
Tim Kuipers 2ee21bf4d2 bugfix support: polygon.simplify(.) removed points 2015-04-21 10:51:36 +02:00
daid cfd5178d54 Let tim sort it out. 2015-04-21 10:42:25 +02:00
Tim Kuipers c1b6e5a8b3 Merge branch 'PinkUnicorn' of https://github.com/Ultimaker/CuraEngine into PinkUnicorn 2015-04-21 09:58:36 +02:00
Tim Kuipers 02b32238d8 perimeterGaps problem fixed (bug that at any angle, perimeter gaps were created and they had infillOverlap) 2015-04-21 09:58:23 +02:00
Arjen Hiemstra 5f47023759 Add print material amount and simplify print time message 2015-04-20 17:54:07 +02:00
Tim Kuipers 68e3966257 Merge branch 'PinkUnicorn' of https://github.com/Ultimaker/CuraEngine into PinkUnicorn 2015-04-20 16:18:53 +02:00
Tim Kuipers 024fed3dc5 remove empty layers better (after insets are generated), fan speed based on setting 'minimalLayerTimeFanSpeedMin' 2015-04-20 16:18:29 +02:00
daid b2e5a290ce Print the wipetower with insetX settings for now (skirt is very slow) 2015-04-20 14:34:29 +02:00
daid 8f9fc7a7b1 Merge branch 'PinkUnicorn' of github.com:Ultimaker/CuraEngine into PinkUnicorn 2015-04-20 14:11:59 +02:00
daid 2bbd2a5cd8 Small fix for dual slicing (for now, we need to take a good look at the object message) 2015-04-20 14:11:47 +02:00
Tim Kuipers 18b476bc33 avoidOverlappingPerimeters refactor and skin perimeters implemented. Also perimeter gaps handled separately from skin. generateLineInfill(.) : added parameter offset_dist instead of always ofsetting with extrudsionWidth/2 2015-04-20 11:03:51 +02:00
Tim Kuipers 06aeff27df Merge branch 'PinkUnicorn' of https://github.com/Ultimaker/CuraEngine into PinkUnicorn 2015-04-17 10:16:08 +02:00
Tim Kuipers 683a1ea99b convex hull (NOT FINISHED) 2015-04-17 10:15:48 +02:00
Tim Kuipers dac08fa727 description of polygons 2015-04-17 09:49:01 +02:00
daid 22cffd2ac6 Reset the printing time when a new slice is done. 2015-04-17 08:47:37 +02:00
daid b2e00b042c Send the proper prefix for UltiGCode for the Ultimaker2. 2015-04-17 08:25:59 +02:00
daid d2240c7228 Bla. 2015-04-15 15:55:50 +02:00
daid 68d00d0d00 Have a different setting for the width of extrusion lines. 2015-04-15 15:26:06 +02:00
daid b37e864cee Add the wipe tower distance as setting. 2015-04-15 15:12:15 +02:00
daid acb58d0ac0 Improve the wipetower. 2015-04-15 15:11:04 +02:00
daid 2edfafb988 Write the Z position after a extruder switch, so we know we are on the proper height again. We know we will move the head in X/Y next, but Z could be moved without our knowledge. 2015-04-15 14:46:29 +02:00
daid 5ea46a44be Small fix for dual-extrusion. 2015-04-15 14:40:14 +02:00
daid a6ec820c1e Fix retraction prime speed. 2015-04-15 13:17:05 +02:00
daid 228b641b8d Also register the new pre/post extruder switch in the setting registry. 2015-04-14 16:31:00 +02:00
daid 22bf8b290a Set pre/post extruder switch code per extruder instead of global for all extruders. 2015-04-14 16:09:56 +02:00
daid c851427848 Allow setting of settings per mesh, useful for dual-extrusion. 2015-04-14 13:53:53 +02:00
daid 8d6d61b3aa Merge mistake. 2015-04-14 13:48:50 +02:00
daid 0787250aca Merge branch 'PinkUnicorn' of github.com:Ultimaker/CuraEngine into PinkUnicorn
Conflicts:
	src/Wireframe2gcode.cpp
2015-04-14 13:47:35 +02:00
daid 2c2492b6ea Fix uint to unsigned int, as uint is not an offical type. 2015-04-14 13:46:41 +02:00
Tim Kuipers 2d8ce2173a GCode_flavor instead of int 2015-04-14 11:42:19 +02:00
Tim Kuipers 35faa0c2ec writeTypeComment refactors 2015-04-14 11:23:44 +02:00
Tim Kuipers 7c5ea7cba4 better concentric infill 2015-04-13 17:29:52 +02:00
Tim Kuipers cace9448df concentric infill with avoidoverlappingPerimeters, lines/zigzag infill bugfix : lines parallel to scanlines resulted in missing points in in_outline polygon 2015-04-13 16:26:38 +02:00
Tim Kuipers 03a13199b4 little cleanup: unsigned int => uint ; removed some unused vars 2015-04-13 15:26:52 +02:00
daid 177d16015b Merge branch 'PinkUnicorn' of github.com:Ultimaker/CuraEngine into PinkUnicorn 2015-04-13 11:41:52 +02:00
daid 54080f7119 Fixed precision problems with commit a9db281 2015-04-13 11:41:42 +02:00
Tim Kuipers 66a0b0275d wireframe command socket stuff 2015-04-13 09:55:22 +02:00
Tim Kuipers 7602f3ccfb Merge branch 'PinkUnicorn' of https://github.com/Ultimaker/CuraEngine into PinkUnicorn 2015-04-08 13:59:36 +02:00
Tim Kuipers dcadf6668a renamed all variables names 'l' to 'layer_idx' etc. 2015-04-08 13:59:07 +02:00
daid 379fee78f4 Merge branch 'PinkUnicorn' of github.com:Ultimaker/CuraEngine into PinkUnicorn 2015-04-08 13:50:25 +02:00
daid d4f3d0c37b Update engine to no longer use temp files to communicate the gcode to the frontend. 2015-04-08 13:45:42 +02:00
Tim Kuipers 0954fef276 finishing wireprinting 2015-04-08 13:44:10 +02:00
Tim Kuipers eb947ef52c merge 2015-04-08 13:34:59 +02:00
Tim Kuipers 0c08bf6ce0 refractoring, cleaning, commenting 2015-04-08 13:31:49 +02:00
daid a9db2813a8 Change the gcode export to use a stream, for later use. Fix a bunch of warings. Add warning level to cmake. 2015-04-07 13:52:15 +02:00
Tim Kuipers 34682fc8a3 fixed better starting point chainify, removed some chainify bugs 2015-04-07 12:31:04 +02:00
Tim Kuipers 9b0b68c75e removed optimizedModel file 2015-04-07 12:17:25 +02:00
TotalRetribution 7d928703a5 Changed option name enableReverseInsetOrder to outerInsetFirst to better explain its function. 2015-04-07 09:59:55 +01:00
Tim Kuipers f9854aead9 removed default settings 2015-04-07 10:58:03 +02:00
Tim Kuipers 468abb641b removed default settings 2015-04-07 10:49:10 +02:00
Tim Kuipers c62774c572 simple back() function for polygons 2015-04-02 16:58:57 +02:00
Tim Kuipers 68f2824fd0 deleted superfluous empty files 2015-04-02 16:58:01 +02:00
Tim Kuipers 556dace457 wireframe refactoring and explanations, roofs still buggy, wireframe printing in debug state! 2015-03-31 15:56:36 +02:00
Tim Kuipers 6f80977b35 Triangles infill added 2015-03-31 13:25:43 +02:00
Tim Kuipers ef8c076a99 wireframe massive refactor; fixed roofs and floors 2015-03-31 11:32:18 +02:00
Tim Kuipers 31ea98a59d documentation overview and glossary 2015-03-27 17:01:16 +01:00
Tim Kuipers 6c05436a0e XYcompensation setting implemented (extra offset to all polygons) 2015-03-27 15:56:42 +01:00
Tim Kuipers 859f37b96c settings registry structuring 2015-03-27 15:24:03 +01:00
TotalRetribution 8961df4342 Add option to Reverse Inset Print Order 2015-03-27 13:36:16 +00:00
Tim Kuipers 05874bb9c4 lil fix 2015-03-27 13:33:49 +01:00
Tim Kuipers ca7353e4d4 remove first empty layers 2015-03-27 13:29:29 +01:00
Tim Kuipers b9d48c9580 bugfix last commit 2015-03-27 13:29:08 +01:00
Tim Kuipers f7edd64f9f imrovement to combined small moves: constant extrusion per second 2015-03-27 11:44:01 +01:00
Tim Kuipers 6fafc0ab29 in the process of correcting roofs and floors bugs, enhanced moves for roofs and floors 2015-03-27 11:37:47 +01:00
Tim Kuipers 93a45c4ed1 roofs fixed and better fill of roofs 2015-03-26 12:35:46 +01:00
Tim Kuipers 05263813f8 roofs fixed and better fill of roofs 2015-03-26 11:35:20 +01:00
Tim Kuipers bb3098e0bc removed very old Atals shite and a lil Weaver bugfix 2015-03-26 09:53:49 +01:00
Tim Kuipers 1288038edf refactorings and better roof handling 2015-03-26 09:46:00 +01:00
Tim Kuipers 33e0083cda starting intermediate roof creation 2015-03-24 17:11:41 +01:00
Tim Kuipers 7a01dbb08f weaver.cpp refactor: connecting separate from chainifying 2015-03-24 16:16:58 +01:00
Tim Kuipers 2cd3bc330c Oh dear I've forgotten to add a very important header file past couple of weeks! 2015-03-24 10:37:04 +01:00
Tim Kuipers eeeadb8221 refactored wireframe printing 2015-03-24 10:36:03 +01:00
Tim Kuipers 290c75669e bottom layer like a roof 2015-03-23 16:02:57 +01:00
Tim Kuipers 0a01ba47e5 neith settings extracted 2015-03-23 14:59:20 +01:00
Tim Kuipers 9b30d16a16 Neith weaver working first approximation; WARNING: gcode.writeMove(.) changed; move with Z component now extrudes more. 2015-03-19 09:45:32 +01:00
Tim Kuipers 01250390de reordering of settings listing 2015-03-19 09:43:08 +01:00
Tim Kuipers c22b1bef74 new intpoint functionality (double multiplication, addition of point and point3, vSizeMM for point3) 2015-03-19 09:42:01 +01:00
Tim Kuipers 4820fbc5ee polygons.remove(other_polygons) 2015-03-19 09:40:54 +01:00
Tim Kuipers 6285f1d1fd Merge branch 'PinkUnicorn' of https://github.com/Ultimaker/CuraEngine into PinkUnicorn 2015-03-16 14:23:23 +01:00
Tim Kuipers 1f77742a18 neith first approximation (no gcode generation yet), bedTemperature setting 2015-03-16 14:22:59 +01:00
Arjen Hiemstra f1a83c18db Generate a proper temp filename on windows 2015-03-13 15:22:52 +01:00
Arjen Hiemstra 8a2956334e Add an id to the GCode message so we can track the object on the ui side 2015-03-13 14:00:11 +01:00
Tim Kuipers ceacaa27b1 changed miter limit for EVERY polygon offset from 2.0 to 1.2 2015-03-13 10:31:34 +01:00
Tim Kuipers 8032c7bfec refactored support, more clarity + more explanations; refactored cupportEverywhere to supportOnBuildplateOnly (and negated appropriately) 2015-03-12 14:21:41 +01:00
Tim Kuipers b3c83ce5e1 removed old grid support./CuraEngine -v -s filamentFlow=100 -s layerThickness=100 -s initialLayerThickness=300 -s supportZDistanceBottom=150 -s supportZDistanceTop=150 -s supportBottomStairDistance=500 -s initialSpeedupLayers=4 -s minimalFeedrate=10 -s preSwitchExtruderCode= -s insetXSpeed=30 -s retractionZHop=0 -s extruderOffset3.X=0 -s extruderOffset3.Y=0 -s gcodeFlavor=GCODE_FLAVOR_ULTIGCODE -s postSwitchExtruderCode= -s retractionSpeed=40 -s infillOverlap=15 -s inset0Speed=20 -s coolHeadLift=0 -s extrusionWidth=400 -s upSkinCount=6 -s initialLayerSpeed=20 -s minimalLayerTime=120 -s infillSpeed=40 -s fanSpeedMax=100 -s enableCombing=1 -s fanSpeedMin=100 -s supportXYDistance=700 -s supportExtruder=-1 -s supportType=ZIGZAG -s supportZDistance=150 -s supportEverywhere=1 -s supportAngle=60 -s supportJoinDistance=600 -s supportBridgeBack=100 -s supportSpeed=20 -s supportConnectZigZags=1 -s supportAreaSmoothing=600 -s supportMinimalAreaSqrt=1000 -s supportTowerDiameter=2000 -s supportTowerRoofAngle=65 -s areaSupportPolyGenerator=1 -s filamentDiameter=1128 -s fanFullOnLayerNr=2 -s extruderOffset1.X=18000 -s extruderOffset1.Y=0 -s endCode=M25 -s minimalExtrusionBeforeRetraction=20 -s retractionMinimalDistance=1500 -s objectSink=5000 -s retractionAmount=4500 -s skinSpeed=25 -s skinPattern=SKIN_LINES -s startCode= 2015-03-12 12:57:07 +01:00
Tim Kuipers f278248402 generateGridInfill refactored ( * 2 outside of function call); removed supportBridgeBack; inBetween perimeters area moved to skin; better wall struts 2015-03-12 12:08:07 +01:00
Tim Kuipers 99f2950cb2 refactor of simplify and smooth 2015-03-11 14:03:29 +01:00
Tim Kuipers 712acb9639 support ON outline instead of within outline; better avoidOverlappingPerimeters insets; sparse areas between perimeters; struts for support walls; polygon smooth(.) and simplify(.) 2015-03-11 13:18:55 +01:00
Tim Kuipers 4b0189b1b6 bugfix: infill overlap was wronggit diff 2015-03-09 15:20:43 +01:00
Tim Kuipers eda8800636 added infill zigzag option 2015-03-09 13:49:24 +01:00
Tim Kuipers 9b95c2f506 refactored generateZigZagSupport to generateZigZagInfill in infill.h; adding zigzag as infill option 2015-03-09 11:41:02 +01:00
Tim Kuipers 6241ec2f5b bugfix : avoid overhang in top notch regions 2015-03-09 11:28:51 +01:00
Tim Kuipers 3d9f8bd740 fixed support bugs and implemented tower support for small overhang areas 2015-03-06 17:25:37 +01:00
Tim Kuipers 3c6f6832a9 new support settings 2015-03-06 17:24:02 +01:00
Tim Kuipers e0e009368d lil improvement of setting handling 2015-03-06 17:22:10 +01:00
Tim Kuipers df29292d8f added support settings for connect_zigzags and area smoothing, modified settings registry 2015-03-05 10:59:08 +01:00
Tim Kuipers 461b41b7e4 bugfix for infill and zigzag support: better iteration over scanlines 2015-03-04 11:10:31 +01:00
Tim Kuipers f02b197322 new option avoidOverlappingPerimetersgit status! 2015-03-04 11:10:04 +01:00
Tim Kuipers 2ef092a720 trying to get all possible settings in a setting registry 2015-03-03 16:18:26 +01:00
Tim Kuipers e305fd4823 lil commit 2015-03-03 16:17:17 +01:00
Tim Kuipers d1e4518961 bugfix when infill of polygons with size 0 2015-03-03 16:16:25 +01:00
Tim Kuipers 3948590ded bugfix crossing infill caused by not finding intersection between polygon and scanline 2015-03-03 11:38:35 +01:00
daid 7b2b9630c7 Merge pull request #161 from mosh1/infill_perimeter_ordering
Add option to change print order of infill vs perimeters. Default prints...
2015-03-03 11:37:04 +01:00
Tim Kuipers a1b0ffc1a7 use printTemp only when given! added settings functionality (hasSetting(.)). moved default settings from main to settings 2015-03-03 10:29:38 +01:00
Tim Kuipers fbbe908f35 zigzag support bugfix of pertruding boundary line piece 2015-03-02 17:06:43 +01:00
Tim Kuipers cdf3215ab3 fixed zigzag spport! some minot bugs exist.. added option to let the support rest on the model in the form of a stair => supportBottomStairDistance 2015-03-02 15:54:01 +01:00
Tim Kuipers faaf5737f2 first zigzag support infill approximation 2015-03-02 13:28:59 +01:00
Tim Kuipers e843d53ec0 removed support skip layer speedup which was buggy 2015-03-02 09:49:14 +01:00
Tim Kuipers cbb080f327 support skip layers additional shite ( support skip layers not working correctlygit diff! ) 2015-03-02 09:35:26 +01:00
Moshen Chan 4621d77a17 Add option to change print order of infill vs perimeters. Default prints infill first as was changed in v15, but this can lead to surface quality issues where infill would show on surface. This adds the option to change the order. 2015-02-27 00:50:50 -08:00
Tim Kuipers 77935a845c bugfix (XYdistance performed double in GCode generation) and speedup in which multiple layers get the same support polygon 2015-02-26 17:00:21 +01:00
Tim Kuipers 62c7c113ca Merge branch 'PinkUnicorn' of https://github.com/Ultimaker/CuraEngine into PinkUnicorn 2015-02-26 15:39:43 +01:00
Tim Kuipers 107aaf0c93 refactoring and removal of old area support computation 2015-02-26 15:39:30 +01:00
Tim Kuipers b90263b481 lil edit 2015-02-26 15:38:46 +01:00
Tim Kuipers d2f6a86e54 added new options and changed default options to arbitrary and bad numbers, but these defaults aren't used right? 2015-02-26 15:04:32 +01:00
Tim Kuipers e0c294238f new area support! new options for it and for toggling between old support and new 2015-02-26 15:03:10 +01:00
Tim Kuipers 487327256a optimized skirt calculations, changed outline smoothing 2015-02-26 15:01:49 +01:00
Arjen Hiemstra e4e0dff046 Send polygons only after we've had a chance to add all of them 2015-02-26 11:50:30 +01:00
Arjen Hiemstra 8e5881d7e4 Do not crash if we try to send polygons after we've already sent them 2015-02-26 11:50:30 +01:00
Arjen Hiemstra 780fe88fe7 Add a function to reset the file number 2015-02-26 11:50:30 +01:00
Tim Kuipers 9f73f59d2e fixed support touching buildplate only and gap between lower layers support structures introduced by XYdistance 2015-02-24 10:49:10 +01:00
Tim Kuipers 6e7cf77e3d Merge branch 'PinkUnicorn' of https://github.com/Ultimaker/CuraEngine into PinkUnicorn 2015-02-24 09:23:19 +01:00
Tim Kuipers 6207419948 bugfixes area support 2015-02-24 09:22:55 +01:00
Tim Kuipers 112cf55ea9 default setting changes in main (note that SOME settings are crappy! 2015-02-20 17:52:01 +01:00
Tim Kuipers b7587a1f1e bugfix: layer z instead of actual z 2015-02-20 17:08:44 +01:00
Tim Kuipers 01a430b052 area support generation 2015-02-20 16:40:29 +01:00
Tim Kuipers bdc12d0bd9 comments for clarification 2015-02-20 11:58:08 +01:00
Tim Kuipers 9b5b035e5e comments for clarification 2015-02-19 17:53:55 +01:00
Tim Kuipers d6f98f2db2 README install instructions 2015-02-19 12:06:14 +01:00
Arjen Hiemstra c0013a4329 Delay the actual processing of the print objects so the memory used for the message can be freed. 2015-02-12 17:49:33 +01:00
Arjen Hiemstra 46774fb1eb Add missing braces so slicing from command line works again 2015-02-12 17:48:38 +01:00
Arjen Hiemstra 327b38094a Properly close the file on a call to GCodeExport::close() 2015-02-12 17:48:13 +01:00
Arjen Hiemstra ffe50c6cb0 Add support for handling settings 2015-02-12 17:47:26 +01:00
Arjen Hiemstra 6b7d61d7db Add SettingList and Setting messages to the protocol 2015-02-12 17:41:39 +01:00
Arjen Hiemstra 6d8b5408bf Update CMakeLists to force c++11 2015-02-11 12:23:03 +01:00
Arjen Hiemstra 408bf5ef12 Update gitignore to exclude kdevelop project files 2015-01-29 11:20:33 +01:00
Arjen Hiemstra 0610c2193e Add a CMakeLists file that looks for libarcus and generates cpp/header files from the proto file 2015-01-29 11:20:10 +01:00
Arjen Hiemstra 866a1b4137 Add Cura protobug protocol file 2015-01-29 11:20:10 +01:00
Arjen Hiemstra 19c9c80c7d Send notifications to the command socket when starting slicing/gcode writing 2015-01-29 11:20:10 +01:00
Arjen Hiemstra 9aba19a738 Simplify command socket handling to a single --connect option 2015-01-29 11:20:10 +01:00
Arjen Hiemstra 616d2305cd Use libArcus for socket communication 2015-01-29 11:19:08 +01:00
Arjen Hiemstra 7be326ba1b Use 0,0 as default position 2015-01-29 11:19:08 +01:00
Arjen Hiemstra f6ec4f3700 Pass floatpoint as const ref in Matrix apply 2015-01-29 11:19:08 +01:00
Arjen Hiemstra ece2d4af18 Use an enum for Polygon type instead of magic strings 2015-01-29 11:18:16 +01:00
Arjen Hiemstra c22499bcc6 Add an assertion so we know what fails if the slicer is called with 0 or less layers 2015-01-29 11:18:16 +01:00
Arjen Hiemstra c12198ac25 Add a close() method to GCodeExport 2015-01-29 11:18:16 +01:00
daid 5a6ebd4156 Merge branch 'master' of github.com:Ultimaker/CuraEngine 2015-01-16 12:17:31 +01:00
daid 0fdec5246b CNC GCode needs P instead of S parameters. 2015-01-16 12:17:22 +01:00
daid bbed68e588 Merge pull request #153 from presslab-us/fixskintravel
Use retract on skins
2015-01-14 14:32:03 +01:00
daid 7ce7123dd9 Prevent uninitialized value. 2015-01-13 10:31:15 +01:00
daid 3ceff11112 Apply patch 2bef59e79b 2015-01-12 15:15:46 +01:00
daid 90c663c6cd Apply 3aa638ea42 2015-01-12 14:51:03 +01:00
daid 51314b765d Apply patch edf2f897d1 2015-01-12 14:45:31 +01:00
daid 445cc29ef0 Apply d7a26ab715 2015-01-12 14:31:27 +01:00
daid ae5aba694f Apply fix 65dc9fe64b 2015-01-12 14:27:01 +01:00
daid 8e570b8fc2 Fix BFB export. 2015-01-12 14:24:30 +01:00
daid 14482d2cf5 Apply commit e72aee5558 2015-01-12 14:17:39 +01:00
Ryan Press 49d5a81d02 Add option to disable combing on skin surfaces
The existing enableCombing options 0, 1 work as before.  A new
option 2 disables combing on the skin surfaces.  This forces a
retract to reduce the unsightly scarring on flat surfaces.
2015-01-09 14:20:52 -08:00
Ryan Press 3e980a84fd slab-us presslab-us authored 5 days ago evert "Use retract on skins"
This reverts commit af14f82a7f.
Because this option should be configurable, change the implementation.
2015-01-09 10:06:39 -08:00
Ryan Press af14f82a7f Use retract on skins
Using combing on skins causes unsightly scarring on flat surfaces.
By forcing a retract between travel moves we can lift the head
above the surface to avoid this.
2015-01-04 14:19:50 -08:00
daid ff4fa3581e Fix the raft printing speed. 2014-12-18 11:02:18 +01:00
daid 2bef59e79b Seperate the skin and infill to give them different speeds. Also change the printing order of this to handle pressure differences better. Which should increase print quality on advanced profiles. 2014-12-16 15:54:55 +01:00
daid 2e5b72cfef Merge pull request #150 from presslab-us/fixpathstart
Reset start position for new layers
2014-12-15 09:59:11 +01:00
Ryan Press 3aa638ea42 Reset start position for new layers
Reset the start position of the path optimizer for each new layer
so that it doesn't double up on the layers, causing problems for
cooling.
2014-12-14 09:08:17 -08:00
daid edf2f897d1 Change how open polygons are saved. As std::vector never clears memory and the old implementation could mean a lot of memory was never freed. 2014-12-12 11:00:33 +01:00
daid cacffadc61 It looks like removing duplicate faces actually has a negative effect on "bad" model. 2014-12-10 08:54:38 +01:00
daid d7a26ab715 Improve skirt handling with support material 2014-12-03 15:39:30 +01:00
daid 951f8f4e4b Added some documentation to the sliceDataStorage. 2014-11-26 14:52:11 +01:00
daid f459c91631 Add some comments to the header of support. 2014-11-26 14:21:11 +01:00
Tim Kuipers b1bf1ccbdc small edge case warning generation 2014-11-24 15:48:45 +01:00
Tim Kuipers 47b75368af mesh doc 2014-11-24 14:15:23 +01:00
Tim Kuipers aa7b1f5c76 bug fixing in mesh 2014-11-24 13:36:37 +01:00
Tim Kuipers ecb365f275 halfedg emesh bugfixing and supportpoint bugfixing 2014-11-19 15:28:23 +01:00
Tim Kuipers 4be5999770 support point generation finished, some bug fixes, made Point3::cross deprecated 2014-11-18 14:51:15 +01:00
Tim Kuipers f4e1a7b1f7 no more forced colorgcc, fix your own linking to colorgcc 2014-11-12 15:25:38 +01:00
Tim Kuipers c771da74d4 colorsgit add colorgcc git add colorgcc git add colorgcc git add colorgcc git add colorgcc git add colorgcc git add colorgcc 2014-11-12 15:08:09 +01:00
Tim Kuipers 914417ee3e added half-edge mesh 2014-11-12 14:51:34 +01:00
Tim Kuipers a4f3656093 removed testing code and hide debugging output 2014-11-12 14:36:31 +01:00
Tim Kuipers 763b9e4827 m
Merge branch 'PinkUnicorn' of https://github.com/Ultimaker/CuraEngine into PinkUnicorn
2014-11-12 14:21:22 +01:00
Tim Kuipers 1231bf6ce0 half-edge meshes and overhang classification of faces, edges and vertices 2014-11-12 14:21:15 +01:00
daid f76510ce26 Fix compile problems for mingw compiler. 2014-10-28 11:09:05 +01:00
daid fa4eafa8e3 Do not change the default build type. 2014-10-28 11:03:38 +01:00
daid 685991cd98 Small fix to the dot score calculation 2014-10-28 11:02:46 +01:00
Tim Kuipers 67771564be refactoring, renaming and commenting 2014-10-23 16:16:43 +02:00
Tim Kuipers 5b67ca1a00 refactoring, renaming, commenting. Splitting pathOrderOptimizer for polygons and edges 2014-10-22 14:53:14 +02:00
daid 5d3d436105 Fix include. 2014-10-22 11:07:26 +02:00
daid ead90e6862 Make the skirt&brim use rounded offsets so they fit better. 2014-10-17 15:59:46 +02:00
daid 92937617f5 Add very basic temperature settings. 2014-10-17 11:26:15 +02:00
daid 0871cd7492 Make the hashPoint function use a const to fix compile issues. 2014-10-01 15:21:56 +02:00
daid 42b6f365c5 Speed up the path-order-optimizer by using a hashmap to look for nearby points. This greatly speeds up the order optimizer when used on infill lines. 2014-09-26 14:55:59 +02:00
daid d1f9e80b5d More additions to the polygon class. 2014-09-25 10:24:48 +02:00
daid 175a3243a5 Small update on polygon and debug functions for more future features. 2014-09-25 09:10:44 +02:00
daid 4c42b16059 Some better parameters for the corner finding routine. 2014-08-29 14:58:32 +02:00
daid 5a4548d426 Try to put the Z seam in internal corners instead of anywhere on the external face. 2014-08-29 14:14:36 +02:00
daid bb587d17d9 Cross-hatch the first support line layer when line support is done. 2014-08-29 12:34:34 +02:00
daid c004124f85 Update support type code to use simple names. 2014-08-29 12:05:10 +02:00
daid 63e81e33d3 Merge branch 'PinkUnicorn' of github.com:Ultimaker/CuraEngine into PinkUnicorn 2014-08-22 15:37:46 +02:00
daid 8b8c385441 Allow setting of settings on object settings as well as mesh level. 2014-08-22 14:59:51 +02:00
daid cad96e24dd Merge pull request #122 from martinxyz/PinkUnicorn
fix build on Linux
2014-08-14 09:14:27 +02:00
Martin Renold c688fc67ef fix build on Linux 2014-08-14 00:01:35 +02:00
daid 68c34fad86 Fix retraction issues after refactoring. 2014-08-13 13:39:10 +02:00
daid 96af51afce Have filament settings per mesh (and thus per extruder) 2014-08-12 13:43:36 +02:00
daid f20fb1aec5 Make speed and retraction settings per mesh. 2014-08-12 10:57:39 +02:00
daid f6d7b77e8e Call mesh->finish so the mesh gets properly optimized and slicing is a lot faster. 2014-08-07 15:44:08 +02:00
daid ce6f78dd89 Fix setting custom build_dir 2014-08-06 10:57:28 +02:00
daid 61ace00ab3 Remove clipperlib.a on clean. 2014-08-06 10:38:20 +02:00
daid 19800c66b8 Update makefile for building windows binary on linux. 2014-08-06 10:34:40 +02:00
daid 69f931b298 Update makefile for building windows binary on linux. 2014-08-06 10:34:05 +02:00
daid 2a15672b98 Merge branch 'PinkUnicorn' of github.com:Ultimaker/CuraEngine into PinkUnicorn 2014-08-05 14:57:39 +02:00
daid 7e788e64b2 Fix extruder offset settings. 2014-08-05 14:57:29 +02:00
Daid 7e59e3b23f Add missing sources. 2014-08-05 14:14:49 +02:00
daid 5f361846bb Some code cleanup. 2014-08-05 14:06:04 +02:00
daid c1c676d892 Remove debug print. 2014-08-05 12:21:24 +02:00
daid 7240dc6ffe move around the ooze shield code, and have the mesh order set by the extruderNr 2014-08-05 11:44:01 +02:00
daid 848a08f4b7 Do not make the extruder number depended on the mesh index, so we can have multiple meshes with the same extruder. 2014-08-05 10:55:33 +02:00
daid 93c2ceae8c Improvements for new settings method 2014-08-05 09:39:15 +02:00
daid 778c26e90c Lots of changes to get to a point where we can define settings per mesh instead of for the whole slice. 2014-08-04 13:36:07 +02:00
daid 9e1d180e81 Remove the ugly UltiGCode hacky code and let the frontend handle this. 2014-07-30 08:39:22 +02:00
daid 4c671418ee Modify UltiGCode flow with the flow setting. Fix problems with the combineSparseLayers generting lots of small areas 2014-07-30 08:26:05 +02:00
daid 95bd012bbe Change the skirt speed handling, as it did not do anything like this. 2014-07-22 10:21:20 +02:00
daid d721ae7daf Merge branch 'master' into PinkUnicorn 2014-07-14 16:46:56 +02:00
daid 21494ffc6c Combine multiple sparse infill layers into a single sparse infill with more extrusion to save printing time. 2014-07-14 16:46:30 +02:00
daid e1a11d0741 Remove the automatic infill pattern (let the caller decide) Add skin fill pattern option. 2014-07-14 13:50:11 +02:00
daid 64faaca516 Do not send raft polygons right now. 2014-07-14 11:52:11 +02:00
daid 54f9620fc5 Slight change how the layers are send towards the frontend. 2014-07-01 11:50:26 +02:00
daid 5c327b7100 Send print information per object. 2014-06-25 11:48:55 +02:00
daid e9e0457238 Merge fix 2014-06-25 09:29:27 +02:00
daid febbdcaf27 Remove old hacky processing. 2014-06-25 09:26:20 +02:00
daid b0e962d37f Track the current object number to send the proper progress update. 2014-06-25 09:23:20 +02:00
daid d0af23d7c8 Merge branch 'master' into PinkUnicorn 2014-06-24 10:31:20 +02:00
daid 548d58cf8e More proper protocol implementation. 2014-06-23 14:56:10 +02:00
daid 35beec7104 Merge branch 'master' into PinkUnicorn 2014-06-23 13:36:40 +02:00
daid 63c6a6e4f4 Implemented new protocol as defined internally with Ultimaker software development team. 2014-06-23 13:33:14 +02:00
daid 4a2f76503c Fix settings from socket, allow sending multiple volumes with different offsets. 2014-06-06 11:28:09 +02:00
daid 0d65ef9ccc Merge branch 'master' into PinkUnicorn 2014-06-05 11:31:32 +02:00
daid 881db618ca Merge fix. 2014-06-05 09:14:16 +02:00
daid 1f64315092 Fix merge 2014-05-27 11:40:17 +02:00
daid 2cb777bfdc Fix slicing for PinkUnicorn. 2014-05-23 13:58:50 +02:00
nallath dd3be7d4c9 Updated makefile 2014-05-21 15:24:37 +02:00
daid 17fe09fff9 Merge branch 'master' into PinkUnicorn 2014-05-20 16:14:03 +02:00
daid 47a996cf15 Merge fix. 2014-05-20 13:01:14 +02:00
daid 1de9da4558 Merge branch 'master' into PinkUnicorn 2014-05-15 13:00:12 +02:00
daid 85fe231dcc Update to working new command socket implementation. 2014-05-08 21:24:53 +02:00
daid 06e9f576b2 Add commandsocket for PinkUnicorn engine communication. 2014-05-08 13:54:30 +02:00
221 arquivos alterados com 43404 adições e 5274 exclusões
+41 -11
Ver Arquivo
@@ -1,20 +1,50 @@
*.tar.bz2
*.tar.gz
*.7z
*.pyc
*.zip
*.exe
.idea
.DS_Store
_bin
_obj
*.depend
*.o
.*.swp
*.gcode
CuraEngine
build/*
*~
NUL
*.gcode
## Building result.
build/*
*.pyc
*.exe
*.a
*.o
CuraEngine
_bin
_obj
## CMake files
cmake_install.cmake
CMakeCache.txt
CMakeFiles/
CPackSourceConfig.cmake
# Visual Studio files generated by CMake
*.vcxproj
*.vcxproj.filters
CuraEngine.sln
# Makefile generated by CMake
Makefile
## IDE project files.
CuraEngine.layout
CuraEngine.cbp
*kdev*
*.kate-swp
nbproject/*
.idea
*.depend
.*.swp
## Documentation.
documentation/html/*
documentation/latex/*
## Test results.
tests/output.xml
callgrind.out.*
+176
Ver Arquivo
@@ -0,0 +1,176 @@
project(CuraEngine)
cmake_minimum_required(VERSION 2.8.12)
option (ENABLE_ARCUS
"Enable support for ARCUS" ON)
if (ENABLE_ARCUS)
message(STATUS "Building with Arcus")
find_package(Arcus REQUIRED)
add_definitions(-DARCUS)
endif ()
if(NOT ${CMAKE_VERSION} VERSION_LESS 3.1)
set(CMAKE_CXX_STANDARD 11)
else()
set(CMAKE_CXX_FLAGS "-std=c++11")
endif()
if(APPLE AND CMAKE_CXX_COMPILER_ID MATCHES "Clang")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11 -stdlib=libc++")
endif()
set(CMAKE_INSTALL_RPATH "${CMAKE_INSTALL_PREFIX}/lib")
set(CURA_ENGINE_VERSION "master" CACHE STRING "Version name of Cura")
option(BUILD_TESTS OFF)
# Add a compiler flag to check the output for insane values if we are in debug mode.
if(CMAKE_BUILD_TYPE MATCHES DEBUG OR CMAKE_BUILD_TYPE MATCHES RelWithDebInfo)
message(STATUS "Building debug release of CuraEngine.")
add_definitions(-DASSERT_INSANE_OUTPUT)
add_definitions(-DUSE_CPU_TIME)
add_definitions(-DDEBUG)
endif()
# Add warnings
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall")
if(NOT APPLE AND NOT WIN32)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -static-libstdc++")
endif()
include_directories(${CMAKE_CURRENT_BINARY_DIR} libs)
add_library(clipper STATIC libs/clipper/clipper.cpp)
set(engine_SRCS # Except main.cpp.
src/bridge.cpp
src/commandSocket.cpp
src/ConicalOverhang.cpp
src/ExtruderTrain.cpp
src/FffGcodeWriter.cpp
src/FffPolygonGenerator.cpp
src/FffProcessor.cpp
src/gcodeExport.cpp
src/GCodePathConfig.cpp
src/gcodePlanner.cpp
src/infill.cpp
src/WallsComputation.cpp
src/layerPart.cpp
src/LayerPlanBuffer.cpp
src/MergeInfillLines.cpp
src/mesh.cpp
src/MeshGroup.cpp
src/multiVolumes.cpp
src/pathOrderOptimizer.cpp
src/Preheat.cpp
src/PrimeTower.cpp
src/raft.cpp
src/skin.cpp
src/SkirtBrim.cpp
src/sliceDataStorage.cpp
src/slicer.cpp
src/support.cpp
src/timeEstimate.cpp
src/WallsComputation.cpp
src/wallOverlap.cpp
src/Weaver.cpp
src/Wireframe2gcode.cpp
src/infill/NoZigZagConnectorProcessor.cpp
src/infill/ZigzagConnectorProcessorConnectedEndPieces.cpp
src/infill/ZigzagConnectorProcessorDisconnectedEndPieces.cpp
src/infill/ZigzagConnectorProcessorEndPieces.cpp
src/infill/ZigzagConnectorProcessorNoEndPieces.cpp
src/pathPlanning/Comb.cpp
src/pathPlanning/LinePolygonsCrossings.cpp
src/progress/Progress.cpp
src/progress/ProgressStageEstimator.cpp
src/settings/SettingConfig.cpp
src/settings/SettingContainer.cpp
src/settings/SettingRegistry.cpp
src/settings/settings.cpp
src/utils/AABB.cpp
src/utils/AABB3D.cpp
src/utils/Date.cpp
src/utils/gettime.cpp
src/utils/LinearAlg2D.cpp
src/utils/ListPolyIt.cpp
src/utils/logoutput.cpp
src/utils/PolygonProximityLinker.cpp
src/utils/polygonUtils.cpp
src/utils/polygon.cpp
src/utils/ProximityPointLink.cpp
)
# List of tests. For each test there must be a file tests/${NAME}.cpp and a file tests/${NAME}.h.
set(engine_TEST
GCodePlannerTest
)
set(engine_TEST_INFILL
)
set(engine_TEST_UTILS
SparseGridTest
LinearAlg2DTest
PolygonUtilsTest
PolygonTest
StringTest
)
# Generating ProtoBuf protocol
if (ENABLE_ARCUS)
protobuf_generate_cpp(engine_PB_SRCS engine_PB_HEADERS Cura.proto)
endif ()
# Compiling CuraEngine itself.
add_library(_CuraEngine ${engine_SRCS} ${engine_PB_SRCS}) #First compile all of CuraEngine as library, allowing this to be re-used for tests.
target_link_libraries(_CuraEngine clipper)
if (ENABLE_ARCUS)
target_link_libraries(_CuraEngine Arcus)
endif ()
set_target_properties(_CuraEngine PROPERTIES COMPILE_DEFINITIONS "VERSION=\"${CURA_ENGINE_VERSION}\"")
if (UNIX)
target_link_libraries(_CuraEngine pthread)
endif()
add_executable(CuraEngine src/main.cpp) #Then compile main.cpp as separate executable, and link the library to it.
target_link_libraries(CuraEngine _CuraEngine)
# Compiling the test environment.
if (BUILD_TESTS)
message(STATUS "Building tests...")
enable_testing()
foreach (test ${engine_TEST})
add_executable(${test} tests/main.cpp tests/${test}.cpp)
target_link_libraries(${test} _CuraEngine cppunit)
add_test(${test} ${test})
endforeach()
foreach (test ${engine_TEST_INFILL})
add_executable(${test} tests/main.cpp tests/infill/${test}.cpp)
target_link_libraries(${test} _CuraEngine cppunit)
add_test(${test} ${test})
endforeach()
foreach (test ${engine_TEST_UTILS})
add_executable(${test} tests/main.cpp tests/utils/${test}.cpp)
target_link_libraries(${test} _CuraEngine cppunit)
add_test(${test} ${test})
endforeach()
endif()
add_custom_command(TARGET CuraEngine POST_BUILD
COMMAND ${CMAKE_COMMAND} -E copy_directory
${CMAKE_SOURCE_DIR}/resources $<TARGET_FILE_DIR:CuraEngine>)
# Installing CuraEngine.
include(GNUInstallDirs)
install(TARGETS CuraEngine DESTINATION ${CMAKE_INSTALL_BINDIR})
include(CPackConfig.cmake)
+20
Ver Arquivo
@@ -0,0 +1,20 @@
set(CPACK_PACKAGE_VENDOR "Ultimaker")
set(CPACK_PACKAGE_CONTACT "Arjen Hiemstra <a.hiemstra@ultimaker.com>")
set(CPACK_PACKAGE_DESCRIPTION_SUMMARY "Cura Engine")
set(CPACK_PACKAGE_VERSION "15.05.90")
set(CPACK_GENERATOR "DEB")
if(NOT DEFINED CPACK_DEBIAN_PACKAGE_ARCHITECTURE)
execute_process(COMMAND dpkg --print-architecture OUTPUT_VARIABLE CPACK_DEBIAN_PACKAGE_ARCHITECTURE OUTPUT_STRIP_TRAILING_WHITESPACE)
endif()
set(CPACK_PACKAGE_FILE_NAME "${CMAKE_PROJECT_NAME}-${CPACK_PACKAGE_VERSION}_${CPACK_DEBIAN_PACKAGE_ARCHITECTURE}")
set(DEB_DEPENDS
"arcus (>= 15.05.90)"
"protobuf (>= 3.0.0)"
"libstdc++6 (>= 4.9.0)"
"libgcc1 (>= 4.9.0)"
)
string(REPLACE ";" ", " DEB_DEPENDS "${DEB_DEPENDS}")
set(CPACK_DEBIAN_PACKAGE_DEPENDS ${DEB_DEPENDS})
include(CPack)
+14
Ver Arquivo
@@ -0,0 +1,14 @@
Changelog CuraEngine
====================
- Feature: infill_wipe_dist. Add a travel move after an infill line in order to let it stick better to the walls.
- Feature: Draft Protection Screen. A shell similar to the ooze shield providing protection from gusts of wind and acting similar to a heated chamber
Release 15.06.01
-----
- [Not documented]
+124
Ver Arquivo
@@ -0,0 +1,124 @@
syntax = "proto3";
package cura.proto;
message ObjectList
{
repeated Object objects = 1;
repeated Setting settings = 2; // meshgroup settings (for one-at-a-time printing)
}
message Slice
{
repeated ObjectList object_lists = 1; // The meshgroups to be printed one after another
SettingList global_settings = 2; // The global settings used for the whole print job
repeated Extruder extruders = 3; // The settings sent to each extruder object
repeated SettingExtruder limit_to_extruder = 4; // From which stack the setting would inherit if not defined per object
}
message Extruder
{
int32 id = 1;
SettingList settings = 2;
}
message Object
{
int64 id = 1;
bytes vertices = 2; //An array of 3 floats.
bytes normals = 3; //An array of 3 floats.
bytes indices = 4; //An array of ints.
repeated Setting settings = 5; // Setting override per object, overruling the global settings.
}
message Progress
{
float amount = 1;
}
message Layer {
int32 id = 1;
float height = 2; // Z position
float thickness = 3; // height of a single layer
repeated Polygon polygons = 4; // layer data
}
message Polygon {
enum Type {
NoneType = 0;
Inset0Type = 1;
InsetXType = 2;
SkinType = 3;
SupportType = 4;
SkirtType = 5;
InfillType = 6;
SupportInfillType = 7;
MoveCombingType = 8;
MoveRetractionType = 9;
SupportInterfaceType = 10;
}
Type type = 1; // Type of move
bytes points = 2; // The points of the polygon, or two points if only a line segment (Currently only line segments are used)
float line_width = 3; // The width of the line being laid down
}
message LayerOptimized {
int32 id = 1;
float height = 2; // Z position
float thickness = 3; // height of a single layer
repeated PathSegment path_segment = 4; // layer data
}
message PathSegment {
int32 extruder = 1; // The extruder used for this path segment
enum PointType {
Point2D = 0;
Point3D = 1;
}
PointType point_type = 2;
bytes points = 3; // The points defining the line segments, bytes of float[2/3] array of length N+1
bytes line_type = 4; // Type of line segment as an unsigned char array of length 1 or N, where N is the number of line segments in this path
bytes line_width = 5; // The widths of the line segments as bytes of a float array of length 1 or N
}
message GCodeLayer {
bytes data = 2;
}
message PrintTimeMaterialEstimates { // The print time for the whole print and material estimates for the extruder
float time = 1; // Total time estimate
repeated MaterialEstimates materialEstimates = 2; // materialEstimates data
}
message MaterialEstimates {
int64 id = 1;
float material_amount = 2; // material used in the extruder
}
message SettingList {
repeated Setting settings = 1;
}
message Setting {
string name = 1; // Internal key to signify a setting
bytes value = 2; // The value of the setting
}
message SettingExtruder {
string name = 1; //The setting key.
int32 extruder = 2; //From which extruder stack the setting should inherit.
}
message GCodePrefix {
bytes data = 2; //Header string to be prepended before the rest of the g-code sent from the engine.
}
message SlicingFinished {
}
+2304
Ver Arquivo
Diferenças do arquivo suprimidas por serem muito extensas Carregar Diff
-89
Ver Arquivo
@@ -1,89 +0,0 @@
#
# Makefile for CuraEngine
#
BUILD_DIR = build
SRC_DIR = src
LIBS_DIR = libs
BUILD_TYPE = RELEASE
VERSION ?= DEV
CXX ?= g++
CFLAGS += -c -Wall -Wextra -Wold-style-cast -Woverloaded-virtual -std=c++11 -DVERSION=\"$(VERSION)\" -isystem libs
ifeq ($(BUILD_TYPE),DEBUG)
CFLAGS+=-ggdb -Og -g
endif
ifeq ($(BUILD_TYPE),PROFILE)
CFLAGS+= -pg
endif
ifeq ($(BUILD_TYPE),RELEASE)
CFLAGS+= -O3 -fomit-frame-pointer
endif
LDFLAGS += -Lbuild/ -lclipper
SOURCES_RAW = bridge.cpp comb.cpp gcodeExport.cpp infill.cpp inset.cpp layerPart.cpp main.cpp optimizedModel.cpp pathOrderOptimizer.cpp polygonOptimizer.cpp raft.cpp settings.cpp skin.cpp skirt.cpp slicer.cpp support.cpp timeEstimate.cpp
SOURCES_RAW += modelFile/modelFile.cpp utils/gettime.cpp utils/logoutput.cpp utils/socket.cpp
SOURCES = $(addprefix $(SRC_DIR)/,$(SOURCES_RAW))
OBJECTS_RAW = $(SOURCES_RAW:.cpp=.o)
OBJECTS = $(addprefix $(BUILD_DIR)/,$(OBJECTS_RAW))
DIRS = $(sort $(dir $(OBJECTS)))
EXECUTABLE = $(BUILD_DIR)/CuraEngine
ifeq ($(OS),Windows_NT)
#For windows make it large address aware, which allows the process to use more then 2GB of memory.
EXECUTABLE := $(EXECUTABLE).exe
CFLAGS += -march=pentium4 -flto
LDFLAGS += -Wl,--large-address-aware -lm -lwsock32 -flto
MKDIR_PREFIX = mkdir -p
else
MKDIR_PREFIX = mkdir -p
UNAME := $(shell uname)
ifeq ($(UNAME), Linux)
OPEN_HTML=firefox
ifeq ($(BUILD_TYPE),DEBUG)
LDFLAGS += --static
else
CFLAGS += -flto
LDFLAGS += --static -flto
endif
endif
ifeq ($(UNAME), OpenBSD)
LDFLAGS += -lm -lpthread
endif
ifeq ($(UNAME), Darwin)
OPEN_HTML=open
#For MacOS force to build
CFLAGS += -force_cpusubtype_ALL -mmacosx-version-min=10.6 -arch x86_64 -arch i386
LDFLAGS += -force_cpusubtype_ALL -mmacosx-version-min=10.6 -arch x86_64 -arch i386
endif
endif
all: $(DIRS) $(SOURCES) $(EXECUTABLE)
$(BUILD_DIR)/libclipper.a: $(LIBS_DIR)/clipper/clipper.cpp
$(CXX) $(CFLAGS) -o $(BUILD_DIR)/libclipper.a $(LIBS_DIR)/clipper/clipper.cpp
$(EXECUTABLE): $(OBJECTS) $(BUILD_DIR)/libclipper.a
$(CXX) $(OBJECTS) -o $@ $(LDFLAGS)
$(DIRS):
-@$(MKDIR_PREFIX) $(DIRS)
$(BUILD_DIR)/%.o: $(SRC_DIR)/%.cpp
$(CXX) $(CFLAGS) $< -o $@
test: $(EXECUTABLE)
python tests/runtest.py $(abspath $(EXECUTABLE))
## clean stuff
clean:
rm -f $(EXECUTABLE) $(OBJECTS) $(BUILD_DIR)/libclipper.a
help:
@cat Makefile |grep \#\#| grep \: |cut -d\# -f3
+53 -3
Ver Arquivo
@@ -3,9 +3,9 @@ CuraEngine
The CuraEngine is a C++ console application for 3D printing GCode generation. It has been made as a better and faster alternative to the old Skeinforge engine.
The CuraEngine is pure C++ and uses Clipper from http://www.angusj.com/delphi/clipper.php
There are no external dependences and Clipper is included in the source code without modifications.
Furthermore it depends on libArcus by Ultimaker, which can be found at http://github.com/Ultimaker/libArcus
This is just a console application for GCode generation. For a full graphical application look at https://github.com/daid/Cura which is the graphical frontend for CuraEngine.
This is just a console application for GCode generation. For a full graphical application look at https://github.com/Ultimaker/Cura which is the graphical frontend for CuraEngine.
The CuraEngine can be used seperately or in other applications. Feel free to add it to your application. But please take note of the License.
@@ -16,6 +16,56 @@ Terms of the license can be found in the LICENSE file. Or at http://www.gnu.org/
But in general it boils down to: You need to share the source of any CuraEngine modifications if you make an application with the CuraEngine. (Even if you make a web-based slicer, you still need to share the source!)
How to Install
==============
1. Clone the repository from https://github.com/Ultimaker/CuraEngine.git (the URL at the right hand side of this page).
2. Install Protobuf >= 3.0.0 (see below)
3. Install libArcus (see https://github.com/Ultimaker/libArcus)
In order to compile CuraEngine, either use CMake or start a project in your preferred IDE.
CMake compilation:
1. Navigate to the CuraEngine directory and execute the following commands
2. ```$ mkdir build && cd build```
3. ```$ cmake ..```
4. ```$ make```
Project files generation:
1. Navigate to the CuraEngine directory and execute the following commands
2. ```cmake . -G "CodeBlocks - Unix Makefiles"```
3. (for a list of supported IDE's see http://www.cmake.org/Wiki/CMake_Generator_Specific_Information#Code::Blocks_Generator)
Installing Protobuf
-------------------
1. Be sure to have libtool installed.
2. Download protobuf from https://github.com/google/protobuf/releases (download ZIP and unZIP at desired location, or clone the repo). The protocol buffer is used for communication between the CuraEngine and the GUI.
3. Run ```autogen.sh``` from the protobuf directory:
```$ ./autogen.sh```
4. ```$ ./configure```
5. ```$ make```
6. ```# make install```
(Please note the ```#```. It indicates the need of superuser, as known as root, priviliges.)
7. (In case the shared library cannot be loaded, you can try ```sudo ldconfig``` on Linux systems)
Running
=======
Other than running CuraEngine from a frontend, such as Ultimaker/Cura, one can run CuraEngine from the command line.
For that one needs a settings JSON file, which can be found in the Ultimaker/Cura repository.
Note that the structure of the json files has changed since 2.1. In the corresponding branch of the Cura repository you can find how the json files used to be structured.
An example run for an UM2 machine looks as follows:
* Navigate to the CuraEngine directory and execute the following
```
./build/CuraEngine slice -v -j ../Cura/resources/definitions/dual_extrusion_printer.def.json -o "output/test.gcode" -e1 -s infill_line_distance=0 -e0 -l "/model_1.stl" -e1 -l "fully_filled_model.stl"
```
Run `CuraEngine help` for a general description of how to use the CuraEngine tool.
[Set the environment variable](https://help.ubuntu.com/community/EnvironmentVariables) CURA_ENGINE_SEARCH_PATH to the appropriate paths, delimited by a colon e.g.
```
CURA_ENGINE_SEARCH_PATH=/path/to/Cura/resources/definitions:/user/defined/path
```
Internals
=========
@@ -78,4 +128,4 @@ The GCode generation is quite a large bit of code. As a lot is going on here. Im
* PathOrderOptimizer: This piece of code needs to solve a TravelingSalesmanProblem. Given a list of polygons/lines it tries to find the best order in which to print them. It currently does this by finding the closest next polygon to print.
* Infill: This code generates a group of lines from an area. This is the code that generates the actuall infill pattern. There is also a concentric infill function, which is currently not used.
* Comb: The combing code is the code that tries to avoid holes when moving the head around without printing. This code also detects when it fails. The final GCode generator uses the combing code while generating the final GCode. So they interact closely.
* GCodeExport: The GCode export is a 2 step process. First it collects all the paths for a layer that it needs to print, this includes all moves, prints, extrusion widths. And then it generates the final GCode. This is the only piece of code that has knowledge about GCode keywords and syntax;meshmdhfdhfdhf to generate a different flavor of GCode it will be the only piece that needs adjustment. All volumatric calculations also happen here.
* GCodeExport: The GCode export is a 2 step process. First it collects all the paths for a layer that it needs to print, this includes all moves, prints, extrusion widths. And then it generates the final GCode. This is the only piece of code that has knowledge about GCode keywords and syntax to generate a different flavor of GCode it will be the only piece that needs adjustment. All volumatric calculations also happen here.
Arquivo binário não exibido.

Depois

Largura:  |  Altura:  |  Tamanho: 18 KiB

Arquivo binário não exibido.

Depois

Largura:  |  Altura:  |  Tamanho: 70 KiB

Arquivo binário não exibido.

Depois

Largura:  |  Altura:  |  Tamanho: 20 KiB

+12
Ver Arquivo
@@ -0,0 +1,12 @@
Glossary
========
Term/Synonyms | Meaning
--- | ---
Extruder Train | The whole of a feeder, bowden tube and a nozzle
Island/Part | isolated/unconnected part in 2D slice
Inset | perimeter, the perimeters which are laid down around the infill
Slicing | The act of extracting the contours of the object at a certain height (not the whole process which would also include gcode generation etc.)
Tower (support) | A strut to reinforce parts of the support which would otherwise be unstable.
Weaver / Neith / WirePrint | A non-layer-wise form of printing 'in thin air'
+10
Ver Arquivo
@@ -0,0 +1,10 @@
CuraEngine {#mainpage}
=======
This is the documentation for CuraEngine, the back-end slicer of Cura.
[Overview](documentation/overview.md)
[Glossary](documentation/glossary.md)
[Code Conventions](https://github.com/Ultimaker/Meta/blob/master/code_conventions.md)
+68
Ver Arquivo
@@ -0,0 +1,68 @@
Overview
========
Internals
---------
The Cura Engine is structured as mainly .h files. This is not standard for an C++ project. However, using less cpp files makes the optimizer work harder and removes linking error issues. It's partialy a result of lazyness but also for optimalizations.
The .h files contain different steps called from the main.cpp file. The main.cpp file contains the global slicing logic.
The slicing process follows the following global steps:
* Load 3D model
* Analize and fix 3D model
* Slice 3D model into 2D layers
* Build LayerParts from sliced layers
* Generate Insets
* Generate up/down skins areas
* Generate sparse infill areas
* Generate GCode for each layer
Each step has more logic in it. But this is a general overview.
All data for the engine is stored in the "SliceDataStorage". It's important to remember that only the data from the previous step is valid.
Coordinates are stored in 64bit integers as microns in the code. So if you see a value of 1000 then this mean 1mm of distance. This is because Clipper works on 64bit integers and microns give a high enough resolution without limiting the size too much. Note that there are some bits and pieces of code that need to be careful about 64bit overflows, especially calculating lengths sqrt(x*x+y*y) can cause overflows.
OptimizedModel
--------------
The OptimizedModel is a 3D model stored with vertex<->face relations. This gives touching face relations which are used later on to slice into layers faster.
Slicer
------
While usually the whole GCode generation process is called Slicing. The slicer in the CuraEngine is the piece of code that generates layers. Each layer has closed 2D polygons.
These polygons are generated in a 2 step process. First all triangles are cut into lines per layer, for each layer a "line segment" is added to that layer.
Next all these line-segments are connected to eachother to make Polygons. The vertex<->face relations of the OptimizedModel help to make this process fast, as there is a huge chance that 2 connecting faces also make 2 connecting line-segments.
This code also fixes up small holes in the 3D model, so your model doesn't need to be perfect Manifold. It also accounts for incorrect normals, so it can flip around line-segments to fit end-to-end.
After the Slicer we have closed Polygons which can be used in Clipper, as Clipper can only opperate on closed 2D polygons.
LayerParts
----------
An important concept to grasp is the LayerParts. LayerParts are seperate parts inside a single layer. For example, if you have a cube. Then each layer has a single LayerPart. However, if you have a table, then the layers which build the legs have a LayerPart per leg, and thus there will be 4 LayerParts.
A LayerPart is a seperated area inside a single layer which does not touch any other LayerParts. Most operations run on LayerParts as it reduces the amount of data to process. During GCode generation handling each LayerPart as an own step makes sure you never travel between LayerParts and thus reducing the amount of external travel.
LayerParts are generated after the Slicer step.
To generate the LayerParts Clipper is used. A Clipper union with extended results gives a list of Polygons with holes in them. Each polygon is a LayerPart, and the holes are added to this LayerPart.
Polygons
--------
Holes are polygons in counter-clockwise (or at-least, in the other direction) and the polygons are guaranteed to be "even-odd", so every crossing of polygon lines will switch from "fill" to "empty".
Insets
------
Insets are also called "Perimeters" or "Loops" sometimes. Generating the insets is only a small bit of code, as Clipper does most of the heavy lifting.
Up/Down skin
------------
The skin code generates the fully filled areas, it does this with some heavy boolean Clipper action. The skin step uses data from different layers to get the job done. Check the code for details.
The sparse infill area code is almost the same as the skin code. With the difference that it keeps the other areas and uses different offsets.
Note that these steps generate the areas, not the actual infill lines. The infill line paths are generated later on. So the result of this step are list of Polygons which are the areas that need to be filled.
GCode generation
----------------
The GCode generation is quite a large bit of code. As a lot is going on here. Important bits here are:
* PathOrderOptimizer: This piece of code needs to solve a TravelingSalesmanProblem. Given a list of polygons/lines it tries to find the best order in which to print them. It currently does this by finding the closest next polygon to print.
* Infill: This code generates a group of lines from an area. This is the code that generates the actuall infill pattern. There is also a concentric infill function, which is currently not used.
* Comb: The combing code is the code that tries to avoid holes when moving around the head without printing. This code also detects when it fails. The final GCode generator uses the combing code while generating the final GCode. So they interact closely.
* GCodeExport: The GCode export is a 2 step process. First it collects all the paths for a layer that it needs to print, this includes all moves, prints, extrusion widths. And then it generates the final GCode. This is the only piece of code that has knowledge about GCode, and to generate a different flavor of GCode it will be the only piece that needs adjustment. All volumatric calculations also happen here.
+19 -21
Ver Arquivo
@@ -1,26 +1,24 @@
The Clipper Library (including Delphi, C++ & C# source code, other accompanying
code, examples and documentation), hereafter called "the Software", has been
released under the following license, terms and conditions:
Boost Software License - Version 1.0 - August 17th, 2003
http://www.boost.org/LICENSE_1_0.txt
Permission is hereby granted, free of charge, to any person or organization
obtaining a copy of the Software covered by this license to use, reproduce,
display, distribute, execute, and transmit the Software, and to prepare
derivative works of the Software, and to permit third-parties to whom the
Software is furnished to do so, all subject to the following:
Permission is hereby granted, free of charge, to any person or organization
obtaining a copy of the software and accompanying documentation covered by
this license (the "Software") to use, reproduce, display, distribute,
execute, and transmit the Software, and to prepare derivative works of the
Software, and to permit third-parties to whom the Software is furnished to
do so, all subject to the following:
The copyright notices in the Software and this entire statement, including the
above license grant, this restriction and the following disclaimer, must be
included in all copies of the Software, in whole or in part, and all derivative
works of the Software, unless such copies or derivative works are solely in the
form of machine-executable object code generated by a source language processor.
The copyright notices in the Software and this entire statement, including
the above license grant, this restriction and the following disclaimer,
must be included in all copies of the Software, in whole or in part, and
all derivative works of the Software, unless such copies or derivative
works are solely in the form of machine-executable object code generated by
a source language processor.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT SHALL
THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE FOR ANY
DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE, ARISING
FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT
SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE
FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE,
ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
DEALINGS IN THE SOFTWARE.
+34 -3
Ver Arquivo
@@ -1,8 +1,39 @@
=====================================================================
Clipper Change Log
=====================================================================
v6.2.1 (31 October 2014) Rev 482
* Bugfix in ClipperOffset.Execute where the Polytree.IsHole property
was returning incorrect values with negative offsets
* Very minor improvement to join rounding in ClipperOffset
* Fixed CPP OpenGL demo.
v6.1.3 (19 January 2014)
v6.2.0 (17 October 2014) Rev 477
* Numerous minor bugfixes, too many to list.
(See revisions 454-475 in Sourceforge Repository)
* The ZFillFunction (custom callback function) has had its parameters
changed.
* Curves demo removed (temporarily).
* Deprecated functions have been removed.
v6.1.5 (26 February 2014) Rev 460
* Improved the joining of output polygons sharing a common edge
when those common edges are horizontal.
* Fixed a bug in ClipperOffset.AddPath() which would produce
incorrect solutions when open paths were added before closed paths.
* Minor code tidy and performance improvement
v6.1.4 (6 February 2014)
* Fixed bugs in MinkowskiSum
* Fixed minor bug when using Clipper.ForceSimplify.
* Modified use_xyz callback so that all 4 vertices around an
intersection point are now passed to the callback function.
v6.1.3a (22 January 2014) Rev 453
* Fixed buggy PointInPolygon function (C++ and C# only).
Note this bug only affected the newly exported function, the
internal PointInPolygon function used by Clipper was OK.
v6.1.3 (19 January 2014) Rev 452
* Fixed potential endless loop condition when adding open
paths to Clipper.
* Fixed missing implementation of SimplifyPolygon function
@@ -13,11 +44,11 @@ v6.1.3 (19 January 2014)
* Overloaded MinkowskiSum function to accommodate multi-contour
paths.
v6.1.2 (15 December 2013)
v6.1.2 (15 December 2013) Rev 444
* Fixed broken C++ header file.
* Minor improvement to joining polygons.
v6.1.1 (13 December 2013)
v6.1.1 (13 December 2013) Rev 441
* Fixed a couple of bugs affecting open paths that could
raise unhandled exceptions.
+388 -534
Ver Arquivo
Diferenças do arquivo suprimidas por serem muito extensas Carregar Diff
+32 -35
Ver Arquivo
@@ -1,8 +1,8 @@
/*******************************************************************************
* *
* Author : Angus Johnson *
* Version : 6.1.3a *
* Date : 22 January 2014 *
* Version : 6.2.1 *
* Date : 31 October 2014 *
* Website : http://www.angusj.com *
* Copyright : Angus Johnson 2010-2014 *
* *
@@ -34,7 +34,7 @@
#ifndef clipper_hpp
#define clipper_hpp
#define CLIPPER_VERSION "6.1.3"
#define CLIPPER_VERSION "6.2.0"
//use_int32: When enabled 32bit ints are used instead of 64bit ints. This
//improve performance but coordinate values are limited to the range +/- 46340
@@ -46,9 +46,8 @@
//use_lines: Enables line clipping. Adds a very minor cost to performance.
//#define use_lines
//use_deprecated: Enables support for the obsolete OffsetPaths() function
//which has been replace with the ClipperOffset class.
#define use_deprecated
//use_deprecated: Enables temporary support for the obsolete functions
//#define use_deprecated
#include <vector>
#include <set>
@@ -57,6 +56,7 @@
#include <cstdlib>
#include <ostream>
#include <functional>
#include <queue>
namespace ClipperLib {
@@ -69,11 +69,16 @@ enum PolyType { ptSubject, ptClip };
enum PolyFillType { pftEvenOdd, pftNonZero, pftPositive, pftNegative };
#ifdef use_int32
typedef int cInt;
typedef unsigned int cUInt;
typedef int cInt;
static cInt const loRange = 0x7FFF;
static cInt const hiRange = 0x7FFF;
#else
typedef signed long long cInt;
typedef unsigned long long cUInt;
typedef signed long long cInt;
static cInt const loRange = 0x3FFFFFFF;
static cInt const hiRange = 0x3FFFFFFFFFFFFFFFLL;
typedef signed long long long64; //used by Int128 class
typedef unsigned long long ulong64;
#endif
struct IntPoint {
@@ -117,15 +122,12 @@ struct DoublePoint
//------------------------------------------------------------------------------
#ifdef use_xyz
typedef void (*TZFillCallback)(IntPoint& z1, IntPoint& z2, IntPoint& pt);
typedef void (*ZFillCallback)(IntPoint& e1bot, IntPoint& e1top, IntPoint& e2bot, IntPoint& e2top, IntPoint& pt);
#endif
enum InitOptions {ioReverseSolution = 1, ioStrictlySimple = 2, ioPreserveCollinear = 4};
enum JoinType {jtSquare, jtRound, jtMiter};
enum EndType {etClosedPolygon, etClosedLine, etOpenButt, etOpenSquare, etOpenRound};
#ifdef use_deprecated
enum EndType_ {etClosed, etButt = 2, etSquare, etRound};
#endif
class PolyNode;
typedef std::vector< PolyNode* > PolyNodes;
@@ -134,6 +136,7 @@ class PolyNode
{
public:
PolyNode();
virtual ~PolyNode(){};
Path Contour;
PolyNodes Childs;
PolyNode* Parent;
@@ -168,11 +171,6 @@ bool Orientation(const Path &poly);
double Area(const Path &poly);
int PointInPolygon(const IntPoint &pt, const Path &path);
#ifdef use_deprecated
void OffsetPaths(const Paths &in_polys, Paths &out_polys,
double delta, JoinType jointype, EndType_ endtype, double limit = 0);
#endif
void SimplifyPolygon(const Path &in_poly, Paths &out_polys, PolyFillType fillType = pftEvenOdd);
void SimplifyPolygons(const Paths &in_polys, Paths &out_polys, PolyFillType fillType = pftEvenOdd);
void SimplifyPolygons(Paths &polys, PolyFillType fillType = pftEvenOdd);
@@ -183,8 +181,7 @@ void CleanPolygons(const Paths& in_polys, Paths& out_polys, double distance = 1.
void CleanPolygons(Paths& polys, double distance = 1.415);
void MinkowskiSum(const Path& pattern, const Path& path, Paths& solution, bool pathIsClosed);
void MinkowskiSum(const Path& pattern, const Paths& paths,
Paths& solution, PolyFillType pathFillType, bool pathIsClosed);
void MinkowskiSum(const Path& pattern, const Paths& paths, Paths& solution, bool pathIsClosed);
void MinkowskiDiff(const Path& poly1, const Path& poly2, Paths& solution);
void PolyTreeToPaths(const PolyTree& polytree, Paths& paths);
@@ -202,7 +199,7 @@ enum EdgeSide { esLeft = 1, esRight = 2};
//forward declarations (for stuff used internally) ...
struct TEdge;
struct IntersectNode;
struct LocalMinima;
struct LocalMinimum;
struct Scanbeam;
struct OutPt;
struct OutRec;
@@ -213,7 +210,6 @@ typedef std::vector < TEdge* > EdgeList;
typedef std::vector < Join* > JoinList;
typedef std::vector < IntersectNode* > IntersectList;
//------------------------------------------------------------------------------
//ClipperBase is the ancestor to the Clipper class. It should not be
@@ -236,12 +232,14 @@ protected:
void PopLocalMinima();
virtual void Reset();
TEdge* ProcessBound(TEdge* E, bool IsClockwise);
void InsertLocalMinima(LocalMinima *newLm);
void DoMinimaLML(TEdge* E1, TEdge* E2, bool IsClosed);
TEdge* DescendToMin(TEdge *&E);
void AscendToMax(TEdge *&E, bool Appending, bool IsClosed);
LocalMinima *m_CurrentLM;
LocalMinima *m_MinimaList;
typedef std::vector<LocalMinimum> MinimaList;
MinimaList::iterator m_CurrentLM;
MinimaList m_MinimaList;
bool m_UseFullRange;
EdgeList m_edges;
bool m_PreserveCollinear;
@@ -268,7 +266,7 @@ public:
void StrictlySimple(bool value) {m_StrictSimple = value;};
//set the callback function for z value filling on intersections (otherwise Z is 0)
#ifdef use_xyz
void ZFillFunction(TZFillCallback zFillFunc);
void ZFillFunction(ZFillCallback zFillFunc);
#endif
protected:
void Reset();
@@ -279,7 +277,8 @@ private:
JoinList m_GhostJoins;
IntersectList m_IntersectList;
ClipType m_ClipType;
std::set< cInt, std::greater<cInt> > m_Scanbeam;
typedef std::priority_queue<cInt> ScanbeamList;
ScanbeamList m_Scanbeam;
TEdge *m_ActiveEdges;
TEdge *m_SortedEdges;
bool m_ExecuteLocked;
@@ -289,7 +288,7 @@ private:
bool m_UsingPolyTree;
bool m_StrictSimple;
#ifdef use_xyz
TZFillCallback m_ZFill; //custom callback
ZFillCallback m_ZFill; //custom callback
#endif
void SetWindingCount(TEdge& edge);
bool IsEvenOddFillType(const TEdge& edge) const;
@@ -308,21 +307,19 @@ private:
bool IsTopHorz(const cInt XPos);
void SwapPositionsInAEL(TEdge *edge1, TEdge *edge2);
void DoMaxima(TEdge *e);
void PrepareHorzJoins(TEdge* horzEdge, bool isTopOfScanbeam);
void ProcessHorizontals(bool IsTopOfScanbeam);
void ProcessHorizontal(TEdge *horzEdge, bool isTopOfScanbeam);
void AddLocalMaxPoly(TEdge *e1, TEdge *e2, const IntPoint &pt);
OutPt* AddLocalMinPoly(TEdge *e1, TEdge *e2, const IntPoint &pt);
OutRec* GetOutRec(int idx);
void AppendPolygon(TEdge *e1, TEdge *e2);
void IntersectEdges(TEdge *e1, TEdge *e2,
const IntPoint &pt, bool protect = false);
void IntersectEdges(TEdge *e1, TEdge *e2, IntPoint &pt);
OutRec* CreateOutRec();
OutPt* AddOutPt(TEdge *e, const IntPoint &pt);
void DisposeAllOutRecs();
void DisposeOutRec(PolyOutList::size_type index);
bool ProcessIntersections(const cInt botY, const cInt topY);
void BuildIntersectList(const cInt botY, const cInt topY);
bool ProcessIntersections(const cInt topY);
void BuildIntersectList(const cInt topY);
void ProcessIntersectList();
void ProcessEdgesAtTopOfScanbeam(const cInt topY);
void BuildResult(Paths& polys);
@@ -344,7 +341,7 @@ private:
void FixupFirstLefts1(OutRec* OldOutRec, OutRec* NewOutRec);
void FixupFirstLefts2(OutRec* OldOutRec, OutRec* NewOutRec);
#ifdef use_xyz
void SetZ(IntPoint& pt, TEdge& e);
void SetZ(IntPoint& pt, TEdge& e1, TEdge& e2);
#endif
};
//------------------------------------------------------------------------------
+249
Ver Arquivo
@@ -0,0 +1,249 @@
// Tencent is pleased to support the open source community by making RapidJSON available.
//
// Copyright (C) 2015 THL A29 Limited, a Tencent company, and Milo Yip. All rights reserved.
//
// Licensed under the MIT License (the "License"); you may not use this file except
// in compliance with the License. You may obtain a copy of the License at
//
// http://opensource.org/licenses/MIT
//
// Unless required by applicable law or agreed to in writing, software distributed
// under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
// CONDITIONS OF ANY KIND, either express or implied. See the License for the
// specific language governing permissions and limitations under the License.
#ifndef RAPIDJSON_ALLOCATORS_H_
#define RAPIDJSON_ALLOCATORS_H_
#include "rapidjson.h"
RAPIDJSON_NAMESPACE_BEGIN
///////////////////////////////////////////////////////////////////////////////
// Allocator
/*! \class rapidjson::Allocator
\brief Concept for allocating, resizing and freeing memory block.
Note that Malloc() and Realloc() are non-static but Free() is static.
So if an allocator need to support Free(), it needs to put its pointer in
the header of memory block.
\code
concept Allocator {
static const bool kNeedFree; //!< Whether this allocator needs to call Free().
// Allocate a memory block.
// \param size of the memory block in bytes.
// \returns pointer to the memory block.
void* Malloc(size_t size);
// Resize a memory block.
// \param originalPtr The pointer to current memory block. Null pointer is permitted.
// \param originalSize The current size in bytes. (Design issue: since some allocator may not book-keep this, explicitly pass to it can save memory.)
// \param newSize the new size in bytes.
void* Realloc(void* originalPtr, size_t originalSize, size_t newSize);
// Free a memory block.
// \param pointer to the memory block. Null pointer is permitted.
static void Free(void *ptr);
};
\endcode
*/
///////////////////////////////////////////////////////////////////////////////
// CrtAllocator
//! C-runtime library allocator.
/*! This class is just wrapper for standard C library memory routines.
\note implements Allocator concept
*/
class CrtAllocator {
public:
static const bool kNeedFree = true;
void* Malloc(size_t size) {
if (size) // behavior of malloc(0) is implementation defined.
return std::malloc(size);
else
return NULL; // standardize to returning NULL.
}
void* Realloc(void* originalPtr, size_t originalSize, size_t newSize) { (void)originalSize; return std::realloc(originalPtr, newSize); }
static void Free(void *ptr) { std::free(ptr); }
};
///////////////////////////////////////////////////////////////////////////////
// MemoryPoolAllocator
//! Default memory allocator used by the parser and DOM.
/*! This allocator allocate memory blocks from pre-allocated memory chunks.
It does not free memory blocks. And Realloc() only allocate new memory.
The memory chunks are allocated by BaseAllocator, which is CrtAllocator by default.
User may also supply a buffer as the first chunk.
If the user-buffer is full then additional chunks are allocated by BaseAllocator.
The user-buffer is not deallocated by this allocator.
\tparam BaseAllocator the allocator type for allocating memory chunks. Default is CrtAllocator.
\note implements Allocator concept
*/
template <typename BaseAllocator = CrtAllocator>
class MemoryPoolAllocator {
public:
static const bool kNeedFree = false; //!< Tell users that no need to call Free() with this allocator. (concept Allocator)
//! Constructor with chunkSize.
/*! \param chunkSize The size of memory chunk. The default is kDefaultChunkSize.
\param baseAllocator The allocator for allocating memory chunks.
*/
MemoryPoolAllocator(size_t chunkSize = kDefaultChunkCapacity, BaseAllocator* baseAllocator = 0) :
chunkHead_(0), chunk_capacity_(chunkSize), userBuffer_(0), baseAllocator_(baseAllocator), ownBaseAllocator_(0)
{
}
//! Constructor with user-supplied buffer.
/*! The user buffer will be used firstly. When it is full, memory pool allocates new chunk with chunk size.
The user buffer will not be deallocated when this allocator is destructed.
\param buffer User supplied buffer.
\param size Size of the buffer in bytes. It must at least larger than sizeof(ChunkHeader).
\param chunkSize The size of memory chunk. The default is kDefaultChunkSize.
\param baseAllocator The allocator for allocating memory chunks.
*/
MemoryPoolAllocator(void *buffer, size_t size, size_t chunkSize = kDefaultChunkCapacity, BaseAllocator* baseAllocator = 0) :
chunkHead_(0), chunk_capacity_(chunkSize), userBuffer_(buffer), baseAllocator_(baseAllocator), ownBaseAllocator_(0)
{
RAPIDJSON_ASSERT(buffer != 0);
RAPIDJSON_ASSERT(size > sizeof(ChunkHeader));
chunkHead_ = reinterpret_cast<ChunkHeader*>(buffer);
chunkHead_->capacity = size - sizeof(ChunkHeader);
chunkHead_->size = 0;
chunkHead_->next = 0;
}
//! Destructor.
/*! This deallocates all memory chunks, excluding the user-supplied buffer.
*/
~MemoryPoolAllocator() {
Clear();
RAPIDJSON_DELETE(ownBaseAllocator_);
}
//! Deallocates all memory chunks, excluding the user-supplied buffer.
void Clear() {
while(chunkHead_ != 0 && chunkHead_ != userBuffer_) {
ChunkHeader* next = chunkHead_->next;
baseAllocator_->Free(chunkHead_);
chunkHead_ = next;
}
}
//! Computes the total capacity of allocated memory chunks.
/*! \return total capacity in bytes.
*/
size_t Capacity() const {
size_t capacity = 0;
for (ChunkHeader* c = chunkHead_; c != 0; c = c->next)
capacity += c->capacity;
return capacity;
}
//! Computes the memory blocks allocated.
/*! \return total used bytes.
*/
size_t Size() const {
size_t size = 0;
for (ChunkHeader* c = chunkHead_; c != 0; c = c->next)
size += c->size;
return size;
}
//! Allocates a memory block. (concept Allocator)
void* Malloc(size_t size) {
if (!size)
return NULL;
size = RAPIDJSON_ALIGN(size);
if (chunkHead_ == 0 || chunkHead_->size + size > chunkHead_->capacity)
AddChunk(chunk_capacity_ > size ? chunk_capacity_ : size);
void *buffer = reinterpret_cast<char *>(chunkHead_ + 1) + chunkHead_->size;
chunkHead_->size += size;
return buffer;
}
//! Resizes a memory block (concept Allocator)
void* Realloc(void* originalPtr, size_t originalSize, size_t newSize) {
if (originalPtr == 0)
return Malloc(newSize);
// Do not shrink if new size is smaller than original
if (originalSize >= newSize)
return originalPtr;
// Simply expand it if it is the last allocation and there is sufficient space
if (originalPtr == (char *)(chunkHead_ + 1) + chunkHead_->size - originalSize) {
size_t increment = static_cast<size_t>(newSize - originalSize);
increment = RAPIDJSON_ALIGN(increment);
if (chunkHead_->size + increment <= chunkHead_->capacity) {
chunkHead_->size += increment;
return originalPtr;
}
}
// Realloc process: allocate and copy memory, do not free original buffer.
void* newBuffer = Malloc(newSize);
RAPIDJSON_ASSERT(newBuffer != 0); // Do not handle out-of-memory explicitly.
if (originalSize)
std::memcpy(newBuffer, originalPtr, originalSize);
return newBuffer;
}
//! Frees a memory block (concept Allocator)
static void Free(void *ptr) { (void)ptr; } // Do nothing
private:
//! Copy constructor is not permitted.
MemoryPoolAllocator(const MemoryPoolAllocator& rhs) /* = delete */;
//! Copy assignment operator is not permitted.
MemoryPoolAllocator& operator=(const MemoryPoolAllocator& rhs) /* = delete */;
//! Creates a new chunk.
/*! \param capacity Capacity of the chunk in bytes.
*/
void AddChunk(size_t capacity) {
if (!baseAllocator_)
ownBaseAllocator_ = baseAllocator_ = RAPIDJSON_NEW(BaseAllocator());
ChunkHeader* chunk = reinterpret_cast<ChunkHeader*>(baseAllocator_->Malloc(sizeof(ChunkHeader) + capacity));
chunk->capacity = capacity;
chunk->size = 0;
chunk->next = chunkHead_;
chunkHead_ = chunk;
}
static const int kDefaultChunkCapacity = 64 * 1024; //!< Default chunk capacity.
//! Chunk header for perpending to each chunk.
/*! Chunks are stored as a singly linked list.
*/
struct ChunkHeader {
size_t capacity; //!< Capacity of the chunk in bytes (excluding the header itself).
size_t size; //!< Current size of allocated memory in bytes.
ChunkHeader *next; //!< Next chunk in the linked list.
};
ChunkHeader *chunkHead_; //!< Head of the chunk linked-list. Only the head chunk serves allocation.
size_t chunk_capacity_; //!< The minimum capacity of chunk when they are allocated.
void *userBuffer_; //!< User supplied buffer.
BaseAllocator* baseAllocator_; //!< base allocator for allocating memory chunks.
BaseAllocator* ownBaseAllocator_; //!< base allocator created by this object.
};
RAPIDJSON_NAMESPACE_END
#endif // RAPIDJSON_ENCODINGS_H_
Diferenças do arquivo suprimidas por serem muito extensas Carregar Diff
+261
Ver Arquivo
@@ -0,0 +1,261 @@
// Tencent is pleased to support the open source community by making RapidJSON available.
//
// Copyright (C) 2015 THL A29 Limited, a Tencent company, and Milo Yip. All rights reserved.
//
// Licensed under the MIT License (the "License"); you may not use this file except
// in compliance with the License. You may obtain a copy of the License at
//
// http://opensource.org/licenses/MIT
//
// Unless required by applicable law or agreed to in writing, software distributed
// under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
// CONDITIONS OF ANY KIND, either express or implied. See the License for the
// specific language governing permissions and limitations under the License.
#ifndef RAPIDJSON_ENCODEDSTREAM_H_
#define RAPIDJSON_ENCODEDSTREAM_H_
#include "rapidjson.h"
#ifdef __GNUC__
RAPIDJSON_DIAG_PUSH
RAPIDJSON_DIAG_OFF(effc++)
#endif
RAPIDJSON_NAMESPACE_BEGIN
//! Input byte stream wrapper with a statically bound encoding.
/*!
\tparam Encoding The interpretation of encoding of the stream. Either UTF8, UTF16LE, UTF16BE, UTF32LE, UTF32BE.
\tparam InputByteStream Type of input byte stream. For example, FileReadStream.
*/
template <typename Encoding, typename InputByteStream>
class EncodedInputStream {
RAPIDJSON_STATIC_ASSERT(sizeof(typename InputByteStream::Ch) == 1);
public:
typedef typename Encoding::Ch Ch;
EncodedInputStream(InputByteStream& is) : is_(is) {
current_ = Encoding::TakeBOM(is_);
}
Ch Peek() const { return current_; }
Ch Take() { Ch c = current_; current_ = Encoding::Take(is_); return c; }
size_t Tell() const { return is_.Tell(); }
// Not implemented
void Put(Ch) { RAPIDJSON_ASSERT(false); }
void Flush() { RAPIDJSON_ASSERT(false); }
Ch* PutBegin() { RAPIDJSON_ASSERT(false); return 0; }
size_t PutEnd(Ch*) { RAPIDJSON_ASSERT(false); return 0; }
private:
EncodedInputStream(const EncodedInputStream&);
EncodedInputStream& operator=(const EncodedInputStream&);
InputByteStream& is_;
Ch current_;
};
//! Output byte stream wrapper with statically bound encoding.
/*!
\tparam Encoding The interpretation of encoding of the stream. Either UTF8, UTF16LE, UTF16BE, UTF32LE, UTF32BE.
\tparam InputByteStream Type of input byte stream. For example, FileWriteStream.
*/
template <typename Encoding, typename OutputByteStream>
class EncodedOutputStream {
RAPIDJSON_STATIC_ASSERT(sizeof(typename OutputByteStream::Ch) == 1);
public:
typedef typename Encoding::Ch Ch;
EncodedOutputStream(OutputByteStream& os, bool putBOM = true) : os_(os) {
if (putBOM)
Encoding::PutBOM(os_);
}
void Put(Ch c) { Encoding::Put(os_, c); }
void Flush() { os_.Flush(); }
// Not implemented
Ch Peek() const { RAPIDJSON_ASSERT(false); }
Ch Take() { RAPIDJSON_ASSERT(false); }
size_t Tell() const { RAPIDJSON_ASSERT(false); return 0; }
Ch* PutBegin() { RAPIDJSON_ASSERT(false); return 0; }
size_t PutEnd(Ch*) { RAPIDJSON_ASSERT(false); return 0; }
private:
EncodedOutputStream(const EncodedOutputStream&);
EncodedOutputStream& operator=(const EncodedOutputStream&);
OutputByteStream& os_;
};
#define RAPIDJSON_ENCODINGS_FUNC(x) UTF8<Ch>::x, UTF16LE<Ch>::x, UTF16BE<Ch>::x, UTF32LE<Ch>::x, UTF32BE<Ch>::x
//! Input stream wrapper with dynamically bound encoding and automatic encoding detection.
/*!
\tparam CharType Type of character for reading.
\tparam InputByteStream type of input byte stream to be wrapped.
*/
template <typename CharType, typename InputByteStream>
class AutoUTFInputStream {
RAPIDJSON_STATIC_ASSERT(sizeof(typename InputByteStream::Ch) == 1);
public:
typedef CharType Ch;
//! Constructor.
/*!
\param is input stream to be wrapped.
\param type UTF encoding type if it is not detected from the stream.
*/
AutoUTFInputStream(InputByteStream& is, UTFType type = kUTF8) : is_(&is), type_(type), hasBOM_(false) {
RAPIDJSON_ASSERT(type >= kUTF8 && type <= kUTF32BE);
DetectType();
static const TakeFunc f[] = { RAPIDJSON_ENCODINGS_FUNC(Take) };
takeFunc_ = f[type_];
current_ = takeFunc_(*is_);
}
UTFType GetType() const { return type_; }
bool HasBOM() const { return hasBOM_; }
Ch Peek() const { return current_; }
Ch Take() { Ch c = current_; current_ = takeFunc_(*is_); return c; }
size_t Tell() const { return is_->Tell(); }
// Not implemented
void Put(Ch) { RAPIDJSON_ASSERT(false); }
void Flush() { RAPIDJSON_ASSERT(false); }
Ch* PutBegin() { RAPIDJSON_ASSERT(false); return 0; }
size_t PutEnd(Ch*) { RAPIDJSON_ASSERT(false); return 0; }
private:
AutoUTFInputStream(const AutoUTFInputStream&);
AutoUTFInputStream& operator=(const AutoUTFInputStream&);
// Detect encoding type with BOM or RFC 4627
void DetectType() {
// BOM (Byte Order Mark):
// 00 00 FE FF UTF-32BE
// FF FE 00 00 UTF-32LE
// FE FF UTF-16BE
// FF FE UTF-16LE
// EF BB BF UTF-8
const unsigned char* c = (const unsigned char *)is_->Peek4();
if (!c)
return;
unsigned bom = c[0] | (c[1] << 8) | (c[2] << 16) | (c[3] << 24);
hasBOM_ = false;
if (bom == 0xFFFE0000) { type_ = kUTF32BE; hasBOM_ = true; is_->Take(); is_->Take(); is_->Take(); is_->Take(); }
else if (bom == 0x0000FEFF) { type_ = kUTF32LE; hasBOM_ = true; is_->Take(); is_->Take(); is_->Take(); is_->Take(); }
else if ((bom & 0xFFFF) == 0xFFFE) { type_ = kUTF16BE; hasBOM_ = true; is_->Take(); is_->Take(); }
else if ((bom & 0xFFFF) == 0xFEFF) { type_ = kUTF16LE; hasBOM_ = true; is_->Take(); is_->Take(); }
else if ((bom & 0xFFFFFF) == 0xBFBBEF) { type_ = kUTF8; hasBOM_ = true; is_->Take(); is_->Take(); is_->Take(); }
// RFC 4627: Section 3
// "Since the first two characters of a JSON text will always be ASCII
// characters [RFC0020], it is possible to determine whether an octet
// stream is UTF-8, UTF-16 (BE or LE), or UTF-32 (BE or LE) by looking
// at the pattern of nulls in the first four octets."
// 00 00 00 xx UTF-32BE
// 00 xx 00 xx UTF-16BE
// xx 00 00 00 UTF-32LE
// xx 00 xx 00 UTF-16LE
// xx xx xx xx UTF-8
if (!hasBOM_) {
unsigned pattern = (c[0] ? 1 : 0) | (c[1] ? 2 : 0) | (c[2] ? 4 : 0) | (c[3] ? 8 : 0);
switch (pattern) {
case 0x08: type_ = kUTF32BE; break;
case 0x0A: type_ = kUTF16BE; break;
case 0x01: type_ = kUTF32LE; break;
case 0x05: type_ = kUTF16LE; break;
case 0x0F: type_ = kUTF8; break;
default: break; // Use type defined by user.
}
}
// Runtime check whether the size of character type is sufficient. It only perform checks with assertion.
if (type_ == kUTF16LE || type_ == kUTF16BE) RAPIDJSON_ASSERT(sizeof(Ch) >= 2);
if (type_ == kUTF32LE || type_ == kUTF32BE) RAPIDJSON_ASSERT(sizeof(Ch) >= 4);
}
typedef Ch (*TakeFunc)(InputByteStream& is);
InputByteStream* is_;
UTFType type_;
Ch current_;
TakeFunc takeFunc_;
bool hasBOM_;
};
//! Output stream wrapper with dynamically bound encoding and automatic encoding detection.
/*!
\tparam CharType Type of character for writing.
\tparam InputByteStream type of output byte stream to be wrapped.
*/
template <typename CharType, typename OutputByteStream>
class AutoUTFOutputStream {
RAPIDJSON_STATIC_ASSERT(sizeof(typename OutputByteStream::Ch) == 1);
public:
typedef CharType Ch;
//! Constructor.
/*!
\param os output stream to be wrapped.
\param type UTF encoding type.
\param putBOM Whether to write BOM at the beginning of the stream.
*/
AutoUTFOutputStream(OutputByteStream& os, UTFType type, bool putBOM) : os_(&os), type_(type) {
RAPIDJSON_ASSERT(type >= kUTF8 && type <= kUTF32BE);
// Runtime check whether the size of character type is sufficient. It only perform checks with assertion.
if (type_ == kUTF16LE || type_ == kUTF16BE) RAPIDJSON_ASSERT(sizeof(Ch) >= 2);
if (type_ == kUTF32LE || type_ == kUTF32BE) RAPIDJSON_ASSERT(sizeof(Ch) >= 4);
static const PutFunc f[] = { RAPIDJSON_ENCODINGS_FUNC(Put) };
putFunc_ = f[type_];
if (putBOM)
PutBOM();
}
UTFType GetType() const { return type_; }
void Put(Ch c) { putFunc_(*os_, c); }
void Flush() { os_->Flush(); }
// Not implemented
Ch Peek() const { RAPIDJSON_ASSERT(false); }
Ch Take() { RAPIDJSON_ASSERT(false); }
size_t Tell() const { RAPIDJSON_ASSERT(false); return 0; }
Ch* PutBegin() { RAPIDJSON_ASSERT(false); return 0; }
size_t PutEnd(Ch*) { RAPIDJSON_ASSERT(false); return 0; }
private:
AutoUTFOutputStream(const AutoUTFOutputStream&);
AutoUTFOutputStream& operator=(const AutoUTFOutputStream&);
void PutBOM() {
typedef void (*PutBOMFunc)(OutputByteStream&);
static const PutBOMFunc f[] = { RAPIDJSON_ENCODINGS_FUNC(PutBOM) };
f[type_](*os_);
}
typedef void (*PutFunc)(OutputByteStream&, Ch);
OutputByteStream* os_;
UTFType type_;
PutFunc putFunc_;
};
#undef RAPIDJSON_ENCODINGS_FUNC
RAPIDJSON_NAMESPACE_END
#ifdef __GNUC__
RAPIDJSON_DIAG_POP
#endif
#endif // RAPIDJSON_FILESTREAM_H_
+625
Ver Arquivo
@@ -0,0 +1,625 @@
// Tencent is pleased to support the open source community by making RapidJSON available.
//
// Copyright (C) 2015 THL A29 Limited, a Tencent company, and Milo Yip. All rights reserved.
//
// Licensed under the MIT License (the "License"); you may not use this file except
// in compliance with the License. You may obtain a copy of the License at
//
// http://opensource.org/licenses/MIT
//
// Unless required by applicable law or agreed to in writing, software distributed
// under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
// CONDITIONS OF ANY KIND, either express or implied. See the License for the
// specific language governing permissions and limitations under the License.
#ifndef RAPIDJSON_ENCODINGS_H_
#define RAPIDJSON_ENCODINGS_H_
#include "rapidjson.h"
#ifdef _MSC_VER
RAPIDJSON_DIAG_PUSH
RAPIDJSON_DIAG_OFF(4244) // conversion from 'type1' to 'type2', possible loss of data
RAPIDJSON_DIAG_OFF(4702) // unreachable code
#elif defined(__GNUC__)
RAPIDJSON_DIAG_PUSH
RAPIDJSON_DIAG_OFF(effc++)
RAPIDJSON_DIAG_OFF(overflow)
#endif
RAPIDJSON_NAMESPACE_BEGIN
///////////////////////////////////////////////////////////////////////////////
// Encoding
/*! \class rapidjson::Encoding
\brief Concept for encoding of Unicode characters.
\code
concept Encoding {
typename Ch; //! Type of character. A "character" is actually a code unit in unicode's definition.
enum { supportUnicode = 1 }; // or 0 if not supporting unicode
//! \brief Encode a Unicode codepoint to an output stream.
//! \param os Output stream.
//! \param codepoint An unicode codepoint, ranging from 0x0 to 0x10FFFF inclusively.
template<typename OutputStream>
static void Encode(OutputStream& os, unsigned codepoint);
//! \brief Decode a Unicode codepoint from an input stream.
//! \param is Input stream.
//! \param codepoint Output of the unicode codepoint.
//! \return true if a valid codepoint can be decoded from the stream.
template <typename InputStream>
static bool Decode(InputStream& is, unsigned* codepoint);
//! \brief Validate one Unicode codepoint from an encoded stream.
//! \param is Input stream to obtain codepoint.
//! \param os Output for copying one codepoint.
//! \return true if it is valid.
//! \note This function just validating and copying the codepoint without actually decode it.
template <typename InputStream, typename OutputStream>
static bool Validate(InputStream& is, OutputStream& os);
// The following functions are deal with byte streams.
//! Take a character from input byte stream, skip BOM if exist.
template <typename InputByteStream>
static CharType TakeBOM(InputByteStream& is);
//! Take a character from input byte stream.
template <typename InputByteStream>
static Ch Take(InputByteStream& is);
//! Put BOM to output byte stream.
template <typename OutputByteStream>
static void PutBOM(OutputByteStream& os);
//! Put a character to output byte stream.
template <typename OutputByteStream>
static void Put(OutputByteStream& os, Ch c);
};
\endcode
*/
///////////////////////////////////////////////////////////////////////////////
// UTF8
//! UTF-8 encoding.
/*! http://en.wikipedia.org/wiki/UTF-8
http://tools.ietf.org/html/rfc3629
\tparam CharType Code unit for storing 8-bit UTF-8 data. Default is char.
\note implements Encoding concept
*/
template<typename CharType = char>
struct UTF8 {
typedef CharType Ch;
enum { supportUnicode = 1 };
template<typename OutputStream>
static void Encode(OutputStream& os, unsigned codepoint) {
if (codepoint <= 0x7F)
os.Put(static_cast<Ch>(codepoint & 0xFF));
else if (codepoint <= 0x7FF) {
os.Put(static_cast<Ch>(0xC0 | ((codepoint >> 6) & 0xFF)));
os.Put(static_cast<Ch>(0x80 | ((codepoint & 0x3F))));
}
else if (codepoint <= 0xFFFF) {
os.Put(static_cast<Ch>(0xE0 | ((codepoint >> 12) & 0xFF)));
os.Put(static_cast<Ch>(0x80 | ((codepoint >> 6) & 0x3F)));
os.Put(static_cast<Ch>(0x80 | (codepoint & 0x3F)));
}
else {
RAPIDJSON_ASSERT(codepoint <= 0x10FFFF);
os.Put(static_cast<Ch>(0xF0 | ((codepoint >> 18) & 0xFF)));
os.Put(static_cast<Ch>(0x80 | ((codepoint >> 12) & 0x3F)));
os.Put(static_cast<Ch>(0x80 | ((codepoint >> 6) & 0x3F)));
os.Put(static_cast<Ch>(0x80 | (codepoint & 0x3F)));
}
}
template <typename InputStream>
static bool Decode(InputStream& is, unsigned* codepoint) {
#define COPY() c = is.Take(); *codepoint = (*codepoint << 6) | ((unsigned char)c & 0x3Fu)
#define TRANS(mask) result &= ((GetRange((unsigned char)c) & mask) != 0)
#define TAIL() COPY(); TRANS(0x70)
Ch c = is.Take();
if (!(c & 0x80)) {
*codepoint = (unsigned char)c;
return true;
}
unsigned char type = GetRange((unsigned char)c);
*codepoint = (0xFF >> type) & (unsigned char)c;
bool result = true;
switch (type) {
case 2: TAIL(); return result;
case 3: TAIL(); TAIL(); return result;
case 4: COPY(); TRANS(0x50); TAIL(); return result;
case 5: COPY(); TRANS(0x10); TAIL(); TAIL(); return result;
case 6: TAIL(); TAIL(); TAIL(); return result;
case 10: COPY(); TRANS(0x20); TAIL(); return result;
case 11: COPY(); TRANS(0x60); TAIL(); TAIL(); return result;
default: return false;
}
#undef COPY
#undef TRANS
#undef TAIL
}
template <typename InputStream, typename OutputStream>
static bool Validate(InputStream& is, OutputStream& os) {
#define COPY() os.Put(c = is.Take())
#define TRANS(mask) result &= ((GetRange((unsigned char)c) & mask) != 0)
#define TAIL() COPY(); TRANS(0x70)
Ch c;
COPY();
if (!(c & 0x80))
return true;
bool result = true;
switch (GetRange((unsigned char)c)) {
case 2: TAIL(); return result;
case 3: TAIL(); TAIL(); return result;
case 4: COPY(); TRANS(0x50); TAIL(); return result;
case 5: COPY(); TRANS(0x10); TAIL(); TAIL(); return result;
case 6: TAIL(); TAIL(); TAIL(); return result;
case 10: COPY(); TRANS(0x20); TAIL(); return result;
case 11: COPY(); TRANS(0x60); TAIL(); TAIL(); return result;
default: return false;
}
#undef COPY
#undef TRANS
#undef TAIL
}
static unsigned char GetRange(unsigned char c) {
// Referring to DFA of http://bjoern.hoehrmann.de/utf-8/decoder/dfa/
// With new mapping 1 -> 0x10, 7 -> 0x20, 9 -> 0x40, such that AND operation can test multiple types.
static const unsigned char type[] = {
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,
0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,
0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,
0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,
8,8,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,
10,3,3,3,3,3,3,3,3,3,3,3,3,4,3,3, 11,6,6,6,5,8,8,8,8,8,8,8,8,8,8,8,
};
return type[c];
}
template <typename InputByteStream>
static CharType TakeBOM(InputByteStream& is) {
RAPIDJSON_STATIC_ASSERT(sizeof(typename InputByteStream::Ch) == 1);
Ch c = Take(is);
if ((unsigned char)c != 0xEFu) return c;
c = is.Take();
if ((unsigned char)c != 0xBBu) return c;
c = is.Take();
if ((unsigned char)c != 0xBFu) return c;
c = is.Take();
return c;
}
template <typename InputByteStream>
static Ch Take(InputByteStream& is) {
RAPIDJSON_STATIC_ASSERT(sizeof(typename InputByteStream::Ch) == 1);
return is.Take();
}
template <typename OutputByteStream>
static void PutBOM(OutputByteStream& os) {
RAPIDJSON_STATIC_ASSERT(sizeof(typename OutputByteStream::Ch) == 1);
os.Put(0xEFu); os.Put(0xBBu); os.Put(0xBFu);
}
template <typename OutputByteStream>
static void Put(OutputByteStream& os, Ch c) {
RAPIDJSON_STATIC_ASSERT(sizeof(typename OutputByteStream::Ch) == 1);
os.Put(static_cast<typename OutputByteStream::Ch>(c));
}
};
///////////////////////////////////////////////////////////////////////////////
// UTF16
//! UTF-16 encoding.
/*! http://en.wikipedia.org/wiki/UTF-16
http://tools.ietf.org/html/rfc2781
\tparam CharType Type for storing 16-bit UTF-16 data. Default is wchar_t. C++11 may use char16_t instead.
\note implements Encoding concept
\note For in-memory access, no need to concern endianness. The code units and code points are represented by CPU's endianness.
For streaming, use UTF16LE and UTF16BE, which handle endianness.
*/
template<typename CharType = wchar_t>
struct UTF16 {
typedef CharType Ch;
RAPIDJSON_STATIC_ASSERT(sizeof(Ch) >= 2);
enum { supportUnicode = 1 };
template<typename OutputStream>
static void Encode(OutputStream& os, unsigned codepoint) {
RAPIDJSON_STATIC_ASSERT(sizeof(typename OutputStream::Ch) >= 2);
if (codepoint <= 0xFFFF) {
RAPIDJSON_ASSERT(codepoint < 0xD800 || codepoint > 0xDFFF); // Code point itself cannot be surrogate pair
os.Put(static_cast<typename OutputStream::Ch>(codepoint));
}
else {
RAPIDJSON_ASSERT(codepoint <= 0x10FFFF);
unsigned v = codepoint - 0x10000;
os.Put(static_cast<typename OutputStream::Ch>((v >> 10) | 0xD800));
os.Put((v & 0x3FF) | 0xDC00);
}
}
template <typename InputStream>
static bool Decode(InputStream& is, unsigned* codepoint) {
RAPIDJSON_STATIC_ASSERT(sizeof(typename InputStream::Ch) >= 2);
Ch c = is.Take();
if (c < 0xD800 || c > 0xDFFF) {
*codepoint = c;
return true;
}
else if (c <= 0xDBFF) {
*codepoint = (c & 0x3FF) << 10;
c = is.Take();
*codepoint |= (c & 0x3FF);
*codepoint += 0x10000;
return c >= 0xDC00 && c <= 0xDFFF;
}
return false;
}
template <typename InputStream, typename OutputStream>
static bool Validate(InputStream& is, OutputStream& os) {
RAPIDJSON_STATIC_ASSERT(sizeof(typename InputStream::Ch) >= 2);
RAPIDJSON_STATIC_ASSERT(sizeof(typename OutputStream::Ch) >= 2);
Ch c;
os.Put(c = is.Take());
if (c < 0xD800 || c > 0xDFFF)
return true;
else if (c <= 0xDBFF) {
os.Put(c = is.Take());
return c >= 0xDC00 && c <= 0xDFFF;
}
return false;
}
};
//! UTF-16 little endian encoding.
template<typename CharType = wchar_t>
struct UTF16LE : UTF16<CharType> {
template <typename InputByteStream>
static CharType TakeBOM(InputByteStream& is) {
RAPIDJSON_STATIC_ASSERT(sizeof(typename InputByteStream::Ch) == 1);
CharType c = Take(is);
return (unsigned short)c == 0xFEFFu ? Take(is) : c;
}
template <typename InputByteStream>
static CharType Take(InputByteStream& is) {
RAPIDJSON_STATIC_ASSERT(sizeof(typename InputByteStream::Ch) == 1);
CharType c = (unsigned char)is.Take();
c |= (unsigned char)is.Take() << 8;
return c;
}
template <typename OutputByteStream>
static void PutBOM(OutputByteStream& os) {
RAPIDJSON_STATIC_ASSERT(sizeof(typename OutputByteStream::Ch) == 1);
os.Put(0xFFu); os.Put(0xFEu);
}
template <typename OutputByteStream>
static void Put(OutputByteStream& os, CharType c) {
RAPIDJSON_STATIC_ASSERT(sizeof(typename OutputByteStream::Ch) == 1);
os.Put(c & 0xFFu);
os.Put((c >> 8) & 0xFFu);
}
};
//! UTF-16 big endian encoding.
template<typename CharType = wchar_t>
struct UTF16BE : UTF16<CharType> {
template <typename InputByteStream>
static CharType TakeBOM(InputByteStream& is) {
RAPIDJSON_STATIC_ASSERT(sizeof(typename InputByteStream::Ch) == 1);
CharType c = Take(is);
return (unsigned short)c == 0xFEFFu ? Take(is) : c;
}
template <typename InputByteStream>
static CharType Take(InputByteStream& is) {
RAPIDJSON_STATIC_ASSERT(sizeof(typename InputByteStream::Ch) == 1);
CharType c = (unsigned char)is.Take() << 8;
c |= (unsigned char)is.Take();
return c;
}
template <typename OutputByteStream>
static void PutBOM(OutputByteStream& os) {
RAPIDJSON_STATIC_ASSERT(sizeof(typename OutputByteStream::Ch) == 1);
os.Put(0xFEu); os.Put(0xFFu);
}
template <typename OutputByteStream>
static void Put(OutputByteStream& os, CharType c) {
RAPIDJSON_STATIC_ASSERT(sizeof(typename OutputByteStream::Ch) == 1);
os.Put((c >> 8) & 0xFFu);
os.Put(c & 0xFFu);
}
};
///////////////////////////////////////////////////////////////////////////////
// UTF32
//! UTF-32 encoding.
/*! http://en.wikipedia.org/wiki/UTF-32
\tparam CharType Type for storing 32-bit UTF-32 data. Default is unsigned. C++11 may use char32_t instead.
\note implements Encoding concept
\note For in-memory access, no need to concern endianness. The code units and code points are represented by CPU's endianness.
For streaming, use UTF32LE and UTF32BE, which handle endianness.
*/
template<typename CharType = unsigned>
struct UTF32 {
typedef CharType Ch;
RAPIDJSON_STATIC_ASSERT(sizeof(Ch) >= 4);
enum { supportUnicode = 1 };
template<typename OutputStream>
static void Encode(OutputStream& os, unsigned codepoint) {
RAPIDJSON_STATIC_ASSERT(sizeof(typename OutputStream::Ch) >= 4);
RAPIDJSON_ASSERT(codepoint <= 0x10FFFF);
os.Put(codepoint);
}
template <typename InputStream>
static bool Decode(InputStream& is, unsigned* codepoint) {
RAPIDJSON_STATIC_ASSERT(sizeof(typename InputStream::Ch) >= 4);
Ch c = is.Take();
*codepoint = c;
return c <= 0x10FFFF;
}
template <typename InputStream, typename OutputStream>
static bool Validate(InputStream& is, OutputStream& os) {
RAPIDJSON_STATIC_ASSERT(sizeof(typename InputStream::Ch) >= 4);
Ch c;
os.Put(c = is.Take());
return c <= 0x10FFFF;
}
};
//! UTF-32 little endian enocoding.
template<typename CharType = unsigned>
struct UTF32LE : UTF32<CharType> {
template <typename InputByteStream>
static CharType TakeBOM(InputByteStream& is) {
RAPIDJSON_STATIC_ASSERT(sizeof(typename InputByteStream::Ch) == 1);
CharType c = Take(is);
return (unsigned)c == 0x0000FEFFu ? Take(is) : c;
}
template <typename InputByteStream>
static CharType Take(InputByteStream& is) {
RAPIDJSON_STATIC_ASSERT(sizeof(typename InputByteStream::Ch) == 1);
CharType c = (unsigned char)is.Take();
c |= (unsigned char)is.Take() << 8;
c |= (unsigned char)is.Take() << 16;
c |= (unsigned char)is.Take() << 24;
return c;
}
template <typename OutputByteStream>
static void PutBOM(OutputByteStream& os) {
RAPIDJSON_STATIC_ASSERT(sizeof(typename OutputByteStream::Ch) == 1);
os.Put(0xFFu); os.Put(0xFEu); os.Put(0x00u); os.Put(0x00u);
}
template <typename OutputByteStream>
static void Put(OutputByteStream& os, CharType c) {
RAPIDJSON_STATIC_ASSERT(sizeof(typename OutputByteStream::Ch) == 1);
os.Put(c & 0xFFu);
os.Put((c >> 8) & 0xFFu);
os.Put((c >> 16) & 0xFFu);
os.Put((c >> 24) & 0xFFu);
}
};
//! UTF-32 big endian encoding.
template<typename CharType = unsigned>
struct UTF32BE : UTF32<CharType> {
template <typename InputByteStream>
static CharType TakeBOM(InputByteStream& is) {
RAPIDJSON_STATIC_ASSERT(sizeof(typename InputByteStream::Ch) == 1);
CharType c = Take(is);
return (unsigned)c == 0x0000FEFFu ? Take(is) : c;
}
template <typename InputByteStream>
static CharType Take(InputByteStream& is) {
RAPIDJSON_STATIC_ASSERT(sizeof(typename InputByteStream::Ch) == 1);
CharType c = (unsigned char)is.Take() << 24;
c |= (unsigned char)is.Take() << 16;
c |= (unsigned char)is.Take() << 8;
c |= (unsigned char)is.Take();
return c;
}
template <typename OutputByteStream>
static void PutBOM(OutputByteStream& os) {
RAPIDJSON_STATIC_ASSERT(sizeof(typename OutputByteStream::Ch) == 1);
os.Put(0x00u); os.Put(0x00u); os.Put(0xFEu); os.Put(0xFFu);
}
template <typename OutputByteStream>
static void Put(OutputByteStream& os, CharType c) {
RAPIDJSON_STATIC_ASSERT(sizeof(typename OutputByteStream::Ch) == 1);
os.Put((c >> 24) & 0xFFu);
os.Put((c >> 16) & 0xFFu);
os.Put((c >> 8) & 0xFFu);
os.Put(c & 0xFFu);
}
};
///////////////////////////////////////////////////////////////////////////////
// ASCII
//! ASCII encoding.
/*! http://en.wikipedia.org/wiki/ASCII
\tparam CharType Code unit for storing 7-bit ASCII data. Default is char.
\note implements Encoding concept
*/
template<typename CharType = char>
struct ASCII {
typedef CharType Ch;
enum { supportUnicode = 0 };
template<typename OutputStream>
static void Encode(OutputStream& os, unsigned codepoint) {
RAPIDJSON_ASSERT(codepoint <= 0x7F);
os.Put(static_cast<Ch>(codepoint & 0xFF));
}
template <typename InputStream>
static bool Decode(InputStream& is, unsigned* codepoint) {
unsigned char c = static_cast<unsigned char>(is.Take());
*codepoint = c;
return c <= 0X7F;
}
template <typename InputStream, typename OutputStream>
static bool Validate(InputStream& is, OutputStream& os) {
unsigned char c = is.Take();
os.Put(c);
return c <= 0x7F;
}
template <typename InputByteStream>
static CharType TakeBOM(InputByteStream& is) {
RAPIDJSON_STATIC_ASSERT(sizeof(typename InputByteStream::Ch) == 1);
Ch c = Take(is);
return c;
}
template <typename InputByteStream>
static Ch Take(InputByteStream& is) {
RAPIDJSON_STATIC_ASSERT(sizeof(typename InputByteStream::Ch) == 1);
return is.Take();
}
template <typename OutputByteStream>
static void PutBOM(OutputByteStream& os) {
RAPIDJSON_STATIC_ASSERT(sizeof(typename OutputByteStream::Ch) == 1);
(void)os;
}
template <typename OutputByteStream>
static void Put(OutputByteStream& os, Ch c) {
RAPIDJSON_STATIC_ASSERT(sizeof(typename OutputByteStream::Ch) == 1);
os.Put(static_cast<typename OutputByteStream::Ch>(c));
}
};
///////////////////////////////////////////////////////////////////////////////
// AutoUTF
//! Runtime-specified UTF encoding type of a stream.
enum UTFType {
kUTF8 = 0, //!< UTF-8.
kUTF16LE = 1, //!< UTF-16 little endian.
kUTF16BE = 2, //!< UTF-16 big endian.
kUTF32LE = 3, //!< UTF-32 little endian.
kUTF32BE = 4 //!< UTF-32 big endian.
};
//! Dynamically select encoding according to stream's runtime-specified UTF encoding type.
/*! \note This class can be used with AutoUTFInputtStream and AutoUTFOutputStream, which provides GetType().
*/
template<typename CharType>
struct AutoUTF {
typedef CharType Ch;
enum { supportUnicode = 1 };
#define RAPIDJSON_ENCODINGS_FUNC(x) UTF8<Ch>::x, UTF16LE<Ch>::x, UTF16BE<Ch>::x, UTF32LE<Ch>::x, UTF32BE<Ch>::x
template<typename OutputStream>
RAPIDJSON_FORCEINLINE static void Encode(OutputStream& os, unsigned codepoint) {
typedef void (*EncodeFunc)(OutputStream&, unsigned);
static const EncodeFunc f[] = { RAPIDJSON_ENCODINGS_FUNC(Encode) };
(*f[os.GetType()])(os, codepoint);
}
template <typename InputStream>
RAPIDJSON_FORCEINLINE static bool Decode(InputStream& is, unsigned* codepoint) {
typedef bool (*DecodeFunc)(InputStream&, unsigned*);
static const DecodeFunc f[] = { RAPIDJSON_ENCODINGS_FUNC(Decode) };
return (*f[is.GetType()])(is, codepoint);
}
template <typename InputStream, typename OutputStream>
RAPIDJSON_FORCEINLINE static bool Validate(InputStream& is, OutputStream& os) {
typedef bool (*ValidateFunc)(InputStream&, OutputStream&);
static const ValidateFunc f[] = { RAPIDJSON_ENCODINGS_FUNC(Validate) };
return (*f[is.GetType()])(is, os);
}
#undef RAPIDJSON_ENCODINGS_FUNC
};
///////////////////////////////////////////////////////////////////////////////
// Transcoder
//! Encoding conversion.
template<typename SourceEncoding, typename TargetEncoding>
struct Transcoder {
//! Take one Unicode codepoint from source encoding, convert it to target encoding and put it to the output stream.
template<typename InputStream, typename OutputStream>
RAPIDJSON_FORCEINLINE static bool Transcode(InputStream& is, OutputStream& os) {
unsigned codepoint;
if (!SourceEncoding::Decode(is, &codepoint))
return false;
TargetEncoding::Encode(os, codepoint);
return true;
}
//! Validate one Unicode codepoint from an encoded stream.
template<typename InputStream, typename OutputStream>
RAPIDJSON_FORCEINLINE static bool Validate(InputStream& is, OutputStream& os) {
return Transcode(is, os); // Since source/target encoding is different, must transcode.
}
};
//! Specialization of Transcoder with same source and target encoding.
template<typename Encoding>
struct Transcoder<Encoding, Encoding> {
template<typename InputStream, typename OutputStream>
RAPIDJSON_FORCEINLINE static bool Transcode(InputStream& is, OutputStream& os) {
os.Put(is.Take()); // Just copy one code unit. This semantic is different from primary template class.
return true;
}
template<typename InputStream, typename OutputStream>
RAPIDJSON_FORCEINLINE static bool Validate(InputStream& is, OutputStream& os) {
return Encoding::Validate(is, os); // source/target encoding are the same
}
};
RAPIDJSON_NAMESPACE_END
#if defined(__GNUC__) || defined(_MSV_VER)
RAPIDJSON_DIAG_POP
#endif
#endif // RAPIDJSON_ENCODINGS_H_
+65
Ver Arquivo
@@ -0,0 +1,65 @@
// Tencent is pleased to support the open source community by making RapidJSON available.
//
// Copyright (C) 2015 THL A29 Limited, a Tencent company, and Milo Yip. All rights reserved.
//
// Licensed under the MIT License (the "License"); you may not use this file except
// in compliance with the License. You may obtain a copy of the License at
//
// http://opensource.org/licenses/MIT
//
// Unless required by applicable law or agreed to in writing, software distributed
// under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
// CONDITIONS OF ANY KIND, either express or implied. See the License for the
// specific language governing permissions and limitations under the License.
#ifndef RAPIDJSON_ERROR_EN_H__
#define RAPIDJSON_ERROR_EN_H__
#include "error.h"
RAPIDJSON_NAMESPACE_BEGIN
//! Maps error code of parsing into error message.
/*!
\ingroup RAPIDJSON_ERRORS
\param parseErrorCode Error code obtained in parsing.
\return the error message.
\note User can make a copy of this function for localization.
Using switch-case is safer for future modification of error codes.
*/
inline const RAPIDJSON_ERROR_CHARTYPE* GetParseError_En(ParseErrorCode parseErrorCode) {
switch (parseErrorCode) {
case kParseErrorNone: return RAPIDJSON_ERROR_STRING("No error.");
case kParseErrorDocumentEmpty: return RAPIDJSON_ERROR_STRING("The document is empty.");
case kParseErrorDocumentRootNotSingular: return RAPIDJSON_ERROR_STRING("The document root must not follow by other values.");
case kParseErrorValueInvalid: return RAPIDJSON_ERROR_STRING("Invalid value.");
case kParseErrorObjectMissName: return RAPIDJSON_ERROR_STRING("Missing a name for object member.");
case kParseErrorObjectMissColon: return RAPIDJSON_ERROR_STRING("Missing a colon after a name of object member.");
case kParseErrorObjectMissCommaOrCurlyBracket: return RAPIDJSON_ERROR_STRING("Missing a comma or '}' after an object member.");
case kParseErrorArrayMissCommaOrSquareBracket: return RAPIDJSON_ERROR_STRING("Missing a comma or ']' after an array element.");
case kParseErrorStringUnicodeEscapeInvalidHex: return RAPIDJSON_ERROR_STRING("Incorrect hex digit after \\u escape in string.");
case kParseErrorStringUnicodeSurrogateInvalid: return RAPIDJSON_ERROR_STRING("The surrogate pair in string is invalid.");
case kParseErrorStringEscapeInvalid: return RAPIDJSON_ERROR_STRING("Invalid escape character in string.");
case kParseErrorStringMissQuotationMark: return RAPIDJSON_ERROR_STRING("Missing a closing quotation mark in string.");
case kParseErrorStringInvalidEncoding: return RAPIDJSON_ERROR_STRING("Invalid encoding in string.");
case kParseErrorNumberTooBig: return RAPIDJSON_ERROR_STRING("Number too big to be stored in double.");
case kParseErrorNumberMissFraction: return RAPIDJSON_ERROR_STRING("Miss fraction part in number.");
case kParseErrorNumberMissExponent: return RAPIDJSON_ERROR_STRING("Miss exponent in number.");
case kParseErrorTermination: return RAPIDJSON_ERROR_STRING("Terminate parsing due to Handler error.");
case kParseErrorUnspecificSyntaxError: return RAPIDJSON_ERROR_STRING("Unspecific syntax error.");
default:
return RAPIDJSON_ERROR_STRING("Unknown error.");
}
}
RAPIDJSON_NAMESPACE_END
#endif // RAPIDJSON_ERROR_EN_H__
+144
Ver Arquivo
@@ -0,0 +1,144 @@
// Tencent is pleased to support the open source community by making RapidJSON available.
//
// Copyright (C) 2015 THL A29 Limited, a Tencent company, and Milo Yip. All rights reserved.
//
// Licensed under the MIT License (the "License"); you may not use this file except
// in compliance with the License. You may obtain a copy of the License at
//
// http://opensource.org/licenses/MIT
//
// Unless required by applicable law or agreed to in writing, software distributed
// under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
// CONDITIONS OF ANY KIND, either express or implied. See the License for the
// specific language governing permissions and limitations under the License.
#ifndef RAPIDJSON_ERROR_ERROR_H__
#define RAPIDJSON_ERROR_ERROR_H__
/*! \file error.h */
/*! \defgroup RAPIDJSON_ERRORS RapidJSON error handling */
///////////////////////////////////////////////////////////////////////////////
// RAPIDJSON_ERROR_CHARTYPE
//! Character type of error messages.
/*! \ingroup RAPIDJSON_ERRORS
The default character type is \c char.
On Windows, user can define this macro as \c TCHAR for supporting both
unicode/non-unicode settings.
*/
#ifndef RAPIDJSON_ERROR_CHARTYPE
#define RAPIDJSON_ERROR_CHARTYPE char
#endif
///////////////////////////////////////////////////////////////////////////////
// RAPIDJSON_ERROR_STRING
//! Macro for converting string literial to \ref RAPIDJSON_ERROR_CHARTYPE[].
/*! \ingroup RAPIDJSON_ERRORS
By default this conversion macro does nothing.
On Windows, user can define this macro as \c _T(x) for supporting both
unicode/non-unicode settings.
*/
#ifndef RAPIDJSON_ERROR_STRING
#define RAPIDJSON_ERROR_STRING(x) x
#endif
RAPIDJSON_NAMESPACE_BEGIN
///////////////////////////////////////////////////////////////////////////////
// ParseErrorCode
//! Error code of parsing.
/*! \ingroup RAPIDJSON_ERRORS
\see GenericReader::Parse, GenericReader::GetParseErrorCode
*/
enum ParseErrorCode {
kParseErrorNone = 0, //!< No error.
kParseErrorDocumentEmpty, //!< The document is empty.
kParseErrorDocumentRootNotSingular, //!< The document root must not follow by other values.
kParseErrorValueInvalid, //!< Invalid value.
kParseErrorObjectMissName, //!< Missing a name for object member.
kParseErrorObjectMissColon, //!< Missing a colon after a name of object member.
kParseErrorObjectMissCommaOrCurlyBracket, //!< Missing a comma or '}' after an object member.
kParseErrorArrayMissCommaOrSquareBracket, //!< Missing a comma or ']' after an array element.
kParseErrorStringUnicodeEscapeInvalidHex, //!< Incorrect hex digit after \\u escape in string.
kParseErrorStringUnicodeSurrogateInvalid, //!< The surrogate pair in string is invalid.
kParseErrorStringEscapeInvalid, //!< Invalid escape character in string.
kParseErrorStringMissQuotationMark, //!< Missing a closing quotation mark in string.
kParseErrorStringInvalidEncoding, //!< Invalid encoding in string.
kParseErrorNumberTooBig, //!< Number too big to be stored in double.
kParseErrorNumberMissFraction, //!< Miss fraction part in number.
kParseErrorNumberMissExponent, //!< Miss exponent in number.
kParseErrorTermination, //!< Parsing was terminated.
kParseErrorUnspecificSyntaxError //!< Unspecific syntax error.
};
//! Result of parsing (wraps ParseErrorCode)
/*!
\ingroup RAPIDJSON_ERRORS
\code
Document doc;
ParseResult ok = doc.Parse("[42]");
if (!ok) {
fprintf(stderr, "JSON parse error: %s (%u)",
GetParseError_En(ok.Code()), ok.Offset());
exit(EXIT_FAILURE);
}
\endcode
\see GenericReader::Parse, GenericDocument::Parse
*/
struct ParseResult {
//! Default constructor, no error.
ParseResult() : code_(kParseErrorNone), offset_(0) {}
//! Constructor to set an error.
ParseResult(ParseErrorCode code, size_t offset) : code_(code), offset_(offset) {}
//! Get the error code.
ParseErrorCode Code() const { return code_; }
//! Get the error offset, if \ref IsError(), 0 otherwise.
size_t Offset() const { return offset_; }
//! Conversion to \c bool, returns \c true, iff !\ref IsError().
operator bool() const { return !IsError(); }
//! Whether the result is an error.
bool IsError() const { return code_ != kParseErrorNone; }
bool operator==(const ParseResult& that) const { return code_ == that.code_; }
bool operator==(ParseErrorCode code) const { return code_ == code; }
friend bool operator==(ParseErrorCode code, const ParseResult & err) { return code == err.code_; }
//! Reset error code.
void Clear() { Set(kParseErrorNone); }
//! Update error code and offset.
void Set(ParseErrorCode code, size_t offset = 0) { code_ = code; offset_ = offset; }
private:
ParseErrorCode code_;
size_t offset_;
};
//! Function pointer type of GetParseError().
/*! \ingroup RAPIDJSON_ERRORS
This is the prototype for \c GetParseError_X(), where \c X is a locale.
User can dynamically change locale in runtime, e.g.:
\code
GetParseErrorFunc GetParseError = GetParseError_En; // or whatever
const RAPIDJSON_ERROR_CHARTYPE* s = GetParseError(document.GetParseErrorCode());
\endcode
*/
typedef const RAPIDJSON_ERROR_CHARTYPE* (*GetParseErrorFunc)(ParseErrorCode);
RAPIDJSON_NAMESPACE_END
#endif // RAPIDJSON_ERROR_ERROR_H__
+88
Ver Arquivo
@@ -0,0 +1,88 @@
// Tencent is pleased to support the open source community by making RapidJSON available.
//
// Copyright (C) 2015 THL A29 Limited, a Tencent company, and Milo Yip. All rights reserved.
//
// Licensed under the MIT License (the "License"); you may not use this file except
// in compliance with the License. You may obtain a copy of the License at
//
// http://opensource.org/licenses/MIT
//
// Unless required by applicable law or agreed to in writing, software distributed
// under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
// CONDITIONS OF ANY KIND, either express or implied. See the License for the
// specific language governing permissions and limitations under the License.
#ifndef RAPIDJSON_FILEREADSTREAM_H_
#define RAPIDJSON_FILEREADSTREAM_H_
#include "rapidjson.h"
#include <cstdio>
RAPIDJSON_NAMESPACE_BEGIN
//! File byte stream for input using fread().
/*!
\note implements Stream concept
*/
class FileReadStream {
public:
typedef char Ch; //!< Character type (byte).
//! Constructor.
/*!
\param fp File pointer opened for read.
\param buffer user-supplied buffer.
\param bufferSize size of buffer in bytes. Must >=4 bytes.
*/
FileReadStream(std::FILE* fp, char* buffer, size_t bufferSize) : fp_(fp), buffer_(buffer), bufferSize_(bufferSize), bufferLast_(0), current_(buffer_), readCount_(0), count_(0), eof_(false) {
RAPIDJSON_ASSERT(fp_ != 0);
RAPIDJSON_ASSERT(bufferSize >= 4);
Read();
}
Ch Peek() const { return *current_; }
Ch Take() { Ch c = *current_; Read(); return c; }
size_t Tell() const { return count_ + static_cast<size_t>(current_ - buffer_); }
// Not implemented
void Put(Ch) { RAPIDJSON_ASSERT(false); }
void Flush() { RAPIDJSON_ASSERT(false); }
Ch* PutBegin() { RAPIDJSON_ASSERT(false); return 0; }
size_t PutEnd(Ch*) { RAPIDJSON_ASSERT(false); return 0; }
// For encoding detection only.
const Ch* Peek4() const {
return (current_ + 4 <= bufferLast_) ? current_ : 0;
}
private:
void Read() {
if (current_ < bufferLast_)
++current_;
else if (!eof_) {
count_ += readCount_;
readCount_ = fread(buffer_, 1, bufferSize_, fp_);
bufferLast_ = buffer_ + readCount_ - 1;
current_ = buffer_;
if (readCount_ < bufferSize_) {
buffer_[readCount_] = '\0';
++bufferLast_;
eof_ = true;
}
}
}
std::FILE* fp_;
Ch *buffer_;
size_t bufferSize_;
Ch *bufferLast_;
Ch *current_;
size_t readCount_;
size_t count_; //!< Number of characters read
bool eof_;
};
RAPIDJSON_NAMESPACE_END
#endif // RAPIDJSON_FILESTREAM_H_
+91
Ver Arquivo
@@ -0,0 +1,91 @@
// Tencent is pleased to support the open source community by making RapidJSON available.
//
// Copyright (C) 2015 THL A29 Limited, a Tencent company, and Milo Yip. All rights reserved.
//
// Licensed under the MIT License (the "License"); you may not use this file except
// in compliance with the License. You may obtain a copy of the License at
//
// http://opensource.org/licenses/MIT
//
// Unless required by applicable law or agreed to in writing, software distributed
// under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
// CONDITIONS OF ANY KIND, either express or implied. See the License for the
// specific language governing permissions and limitations under the License.
#ifndef RAPIDJSON_FILEWRITESTREAM_H_
#define RAPIDJSON_FILEWRITESTREAM_H_
#include "rapidjson.h"
#include <cstdio>
RAPIDJSON_NAMESPACE_BEGIN
//! Wrapper of C file stream for input using fread().
/*!
\note implements Stream concept
*/
class FileWriteStream {
public:
typedef char Ch; //!< Character type. Only support char.
FileWriteStream(std::FILE* fp, char* buffer, size_t bufferSize) : fp_(fp), buffer_(buffer), bufferEnd_(buffer + bufferSize), current_(buffer_) {
RAPIDJSON_ASSERT(fp_ != 0);
}
void Put(char c) {
if (current_ >= bufferEnd_)
Flush();
*current_++ = c;
}
void PutN(char c, size_t n) {
size_t avail = static_cast<size_t>(bufferEnd_ - current_);
while (n > avail) {
std::memset(current_, c, avail);
current_ += avail;
Flush();
n -= avail;
avail = static_cast<size_t>(bufferEnd_ - current_);
}
if (n > 0) {
std::memset(current_, c, n);
current_ += n;
}
}
void Flush() {
if (current_ != buffer_) {
fwrite(buffer_, 1, static_cast<size_t>(current_ - buffer_), fp_);
current_ = buffer_;
}
}
// Not implemented
char Peek() const { RAPIDJSON_ASSERT(false); return 0; }
char Take() { RAPIDJSON_ASSERT(false); return 0; }
size_t Tell() const { RAPIDJSON_ASSERT(false); return 0; }
char* PutBegin() { RAPIDJSON_ASSERT(false); return 0; }
size_t PutEnd(char*) { RAPIDJSON_ASSERT(false); return 0; }
private:
// Prohibit copy constructor & assignment operator.
FileWriteStream(const FileWriteStream&);
FileWriteStream& operator=(const FileWriteStream&);
std::FILE* fp_;
char *buffer_;
char *bufferEnd_;
char *current_;
};
//! Implement specialized version of PutN() with memset() for better performance.
template<>
inline void PutN(FileWriteStream& stream, char c, size_t n) {
stream.PutN(c, n);
}
RAPIDJSON_NAMESPACE_END
#endif // RAPIDJSON_FILESTREAM_H_
+280
Ver Arquivo
@@ -0,0 +1,280 @@
// Tencent is pleased to support the open source community by making RapidJSON available.
//
// Copyright (C) 2015 THL A29 Limited, a Tencent company, and Milo Yip. All rights reserved.
//
// Licensed under the MIT License (the "License"); you may not use this file except
// in compliance with the License. You may obtain a copy of the License at
//
// http://opensource.org/licenses/MIT
//
// Unless required by applicable law or agreed to in writing, software distributed
// under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
// CONDITIONS OF ANY KIND, either express or implied. See the License for the
// specific language governing permissions and limitations under the License.
#ifndef RAPIDJSON_BIGINTEGER_H_
#define RAPIDJSON_BIGINTEGER_H_
#include "../rapidjson.h"
#if defined(_MSC_VER) && defined(_M_AMD64)
#include <intrin.h> // for _umul128
#endif
RAPIDJSON_NAMESPACE_BEGIN
namespace internal {
class BigInteger {
public:
typedef uint64_t Type;
BigInteger(const BigInteger& rhs) : count_(rhs.count_) {
std::memcpy(digits_, rhs.digits_, count_ * sizeof(Type));
}
explicit BigInteger(uint64_t u) : count_(1) {
digits_[0] = u;
}
BigInteger(const char* decimals, size_t length) : count_(1) {
RAPIDJSON_ASSERT(length > 0);
digits_[0] = 0;
size_t i = 0;
const size_t kMaxDigitPerIteration = 19; // 2^64 = 18446744073709551616 > 10^19
while (length >= kMaxDigitPerIteration) {
AppendDecimal64(decimals + i, decimals + i + kMaxDigitPerIteration);
length -= kMaxDigitPerIteration;
i += kMaxDigitPerIteration;
}
if (length > 0)
AppendDecimal64(decimals + i, decimals + i + length);
}
BigInteger& operator=(uint64_t u) {
digits_[0] = u;
count_ = 1;
return *this;
}
BigInteger& operator+=(uint64_t u) {
Type backup = digits_[0];
digits_[0] += u;
for (size_t i = 0; i < count_ - 1; i++) {
if (digits_[i] >= backup)
return *this; // no carry
backup = digits_[i + 1];
digits_[i + 1] += 1;
}
// Last carry
if (digits_[count_ - 1] < backup)
PushBack(1);
return *this;
}
BigInteger& operator*=(uint64_t u) {
if (u == 0) return *this = 0;
if (u == 1) return *this;
if (*this == 1) return *this = u;
uint64_t k = 0;
for (size_t i = 0; i < count_; i++) {
uint64_t hi;
digits_[i] = MulAdd64(digits_[i], u, k, &hi);
k = hi;
}
if (k > 0)
PushBack(k);
return *this;
}
BigInteger& operator*=(uint32_t u) {
if (u == 0) return *this = 0;
if (u == 1) return *this;
if (*this == 1) return *this = u;
uint32_t k = 0;
for (size_t i = 0; i < count_; i++) {
const uint64_t c = digits_[i] >> 32;
const uint64_t d = digits_[i] & 0xFFFFFFFF;
const uint64_t uc = u * c;
const uint64_t ud = u * d;
const uint64_t p0 = ud + k;
const uint64_t p1 = uc + (p0 >> 32);
digits_[i] = (p0 & 0xFFFFFFFF) | (p1 << 32);
k = p1 >> 32;
}
if (k > 0)
PushBack(k);
return *this;
}
BigInteger& operator<<=(size_t shift) {
if (IsZero() || shift == 0) return *this;
size_t offset = shift / kTypeBit;
size_t interShift = shift % kTypeBit;
RAPIDJSON_ASSERT(count_ + offset <= kCapacity);
if (interShift == 0) {
std::memmove(&digits_[count_ - 1 + offset], &digits_[count_ - 1], count_ * sizeof(Type));
count_ += offset;
}
else {
digits_[count_] = 0;
for (size_t i = count_; i > 0; i--)
digits_[i + offset] = (digits_[i] << interShift) | (digits_[i - 1] >> (kTypeBit - interShift));
digits_[offset] = digits_[0] << interShift;
count_ += offset;
if (digits_[count_])
count_++;
}
std::memset(digits_, 0, offset * sizeof(Type));
return *this;
}
bool operator==(const BigInteger& rhs) const {
return count_ == rhs.count_ && std::memcmp(digits_, rhs.digits_, count_ * sizeof(Type)) == 0;
}
bool operator==(const Type rhs) const {
return count_ == 1 && digits_[0] == rhs;
}
BigInteger& MultiplyPow5(unsigned exp) {
static const uint32_t kPow5[12] = {
5,
5 * 5,
5 * 5 * 5,
5 * 5 * 5 * 5,
5 * 5 * 5 * 5 * 5,
5 * 5 * 5 * 5 * 5 * 5,
5 * 5 * 5 * 5 * 5 * 5 * 5,
5 * 5 * 5 * 5 * 5 * 5 * 5 * 5,
5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5,
5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5,
5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5,
5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5
};
if (exp == 0) return *this;
for (; exp >= 27; exp -= 27) *this *= RAPIDJSON_UINT64_C2(0X6765C793, 0XFA10079D); // 5^27
for (; exp >= 13; exp -= 13) *this *= static_cast<uint32_t>(1220703125u); // 5^13
if (exp > 0) *this *= kPow5[exp - 1];
return *this;
}
// Compute absolute difference of this and rhs.
// Assume this != rhs
bool Difference(const BigInteger& rhs, BigInteger* out) const {
int cmp = Compare(rhs);
RAPIDJSON_ASSERT(cmp != 0);
const BigInteger *a, *b; // Makes a > b
bool ret;
if (cmp < 0) { a = &rhs; b = this; ret = true; }
else { a = this; b = &rhs; ret = false; }
Type borrow = 0;
for (size_t i = 0; i < a->count_; i++) {
Type d = a->digits_[i] - borrow;
if (i < b->count_)
d -= b->digits_[i];
borrow = (d > a->digits_[i]) ? 1 : 0;
out->digits_[i] = d;
if (d != 0)
out->count_ = i + 1;
}
return ret;
}
int Compare(const BigInteger& rhs) const {
if (count_ != rhs.count_)
return count_ < rhs.count_ ? -1 : 1;
for (size_t i = count_; i-- > 0;)
if (digits_[i] != rhs.digits_[i])
return digits_[i] < rhs.digits_[i] ? -1 : 1;
return 0;
}
size_t GetCount() const { return count_; }
Type GetDigit(size_t index) const { RAPIDJSON_ASSERT(index < count_); return digits_[index]; }
bool IsZero() const { return count_ == 1 && digits_[0] == 0; }
private:
void AppendDecimal64(const char* begin, const char* end) {
uint64_t u = ParseUint64(begin, end);
if (IsZero())
*this = u;
else {
unsigned exp = static_cast<unsigned>(end - begin);
(MultiplyPow5(exp) <<= exp) += u; // *this = *this * 10^exp + u
}
}
void PushBack(Type digit) {
RAPIDJSON_ASSERT(count_ < kCapacity);
digits_[count_++] = digit;
}
static uint64_t ParseUint64(const char* begin, const char* end) {
uint64_t r = 0;
for (const char* p = begin; p != end; ++p) {
RAPIDJSON_ASSERT(*p >= '0' && *p <= '9');
r = r * 10 + (*p - '0');
}
return r;
}
// Assume a * b + k < 2^128
static uint64_t MulAdd64(uint64_t a, uint64_t b, uint64_t k, uint64_t* outHigh) {
#if defined(_MSC_VER) && defined(_M_AMD64)
uint64_t low = _umul128(a, b, outHigh) + k;
if (low < k)
(*outHigh)++;
return low;
#elif (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 6)) && defined(__x86_64__)
__extension__ typedef unsigned __int128 uint128;
uint128 p = static_cast<uint128>(a) * static_cast<uint128>(b);
p += k;
*outHigh = p >> 64;
return static_cast<uint64_t>(p);
#else
const uint64_t a0 = a & 0xFFFFFFFF, a1 = a >> 32, b0 = b & 0xFFFFFFFF, b1 = b >> 32;
uint64_t x0 = a0 * b0, x1 = a0 * b1, x2 = a1 * b0, x3 = a1 * b1;
x1 += (x0 >> 32); // can't give carry
x1 += x2;
if (x1 < x2)
x3 += (static_cast<uint64_t>(1) << 32);
uint64_t lo = (x1 << 32) + (x0 & 0xFFFFFFFF);
uint64_t hi = x3 + (x1 >> 32);
lo += k;
if (lo < k)
hi++;
*outHigh = hi;
return lo;
#endif
}
static const size_t kBitCount = 3328; // 64bit * 54 > 10^1000
static const size_t kCapacity = kBitCount / sizeof(Type);
static const size_t kTypeBit = sizeof(Type) * 8;
Type digits_[kCapacity];
size_t count_;
};
} // namespace internal
RAPIDJSON_NAMESPACE_END
#endif // RAPIDJSON_BIGINTEGER_H_
+247
Ver Arquivo
@@ -0,0 +1,247 @@
// Tencent is pleased to support the open source community by making RapidJSON available.
//
// Copyright (C) 2015 THL A29 Limited, a Tencent company, and Milo Yip. All rights reserved.
//
// Licensed under the MIT License (the "License"); you may not use this file except
// in compliance with the License. You may obtain a copy of the License at
//
// http://opensource.org/licenses/MIT
//
// Unless required by applicable law or agreed to in writing, software distributed
// under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
// CONDITIONS OF ANY KIND, either express or implied. See the License for the
// specific language governing permissions and limitations under the License.
// This is a C++ header-only implementation of Grisu2 algorithm from the publication:
// Loitsch, Florian. "Printing floating-point numbers quickly and accurately with
// integers." ACM Sigplan Notices 45.6 (2010): 233-243.
#ifndef RAPIDJSON_DIYFP_H_
#define RAPIDJSON_DIYFP_H_
#if defined(_MSC_VER)
#include <intrin.h>
#if defined(_M_AMD64)
#pragma intrinsic(_BitScanReverse64)
#endif
#endif
RAPIDJSON_NAMESPACE_BEGIN
namespace internal {
#ifdef __GNUC__
RAPIDJSON_DIAG_PUSH
RAPIDJSON_DIAG_OFF(effc++)
#endif
struct DiyFp {
DiyFp() {}
DiyFp(uint64_t fp, int exp) : f(fp), e(exp) {}
explicit DiyFp(double d) {
union {
double d;
uint64_t u64;
} u = { d };
int biased_e = (u.u64 & kDpExponentMask) >> kDpSignificandSize;
uint64_t significand = (u.u64 & kDpSignificandMask);
if (biased_e != 0) {
f = significand + kDpHiddenBit;
e = biased_e - kDpExponentBias;
}
else {
f = significand;
e = kDpMinExponent + 1;
}
}
DiyFp operator-(const DiyFp& rhs) const {
return DiyFp(f - rhs.f, e);
}
DiyFp operator*(const DiyFp& rhs) const {
#if defined(_MSC_VER) && defined(_M_AMD64)
uint64_t h;
uint64_t l = _umul128(f, rhs.f, &h);
if (l & (uint64_t(1) << 63)) // rounding
h++;
return DiyFp(h, e + rhs.e + 64);
#elif (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 6)) && defined(__x86_64__)
__extension__ typedef unsigned __int128 uint128;
uint128 p = static_cast<uint128>(f) * static_cast<uint128>(rhs.f);
uint64_t h = p >> 64;
uint64_t l = static_cast<uint64_t>(p);
if (l & (uint64_t(1) << 63)) // rounding
h++;
return DiyFp(h, e + rhs.e + 64);
#else
const uint64_t M32 = 0xFFFFFFFF;
const uint64_t a = f >> 32;
const uint64_t b = f & M32;
const uint64_t c = rhs.f >> 32;
const uint64_t d = rhs.f & M32;
const uint64_t ac = a * c;
const uint64_t bc = b * c;
const uint64_t ad = a * d;
const uint64_t bd = b * d;
uint64_t tmp = (bd >> 32) + (ad & M32) + (bc & M32);
tmp += 1U << 31; /// mult_round
return DiyFp(ac + (ad >> 32) + (bc >> 32) + (tmp >> 32), e + rhs.e + 64);
#endif
}
DiyFp Normalize() const {
#if defined(_MSC_VER) && defined(_M_AMD64)
unsigned long index;
_BitScanReverse64(&index, f);
return DiyFp(f << (63 - index), e - (63 - index));
#elif defined(__GNUC__) && __GNUC__ >= 4
int s = __builtin_clzll(f);
return DiyFp(f << s, e - s);
#else
DiyFp res = *this;
while (!(res.f & (static_cast<uint64_t>(1) << 63))) {
res.f <<= 1;
res.e--;
}
return res;
#endif
}
DiyFp NormalizeBoundary() const {
DiyFp res = *this;
while (!(res.f & (kDpHiddenBit << 1))) {
res.f <<= 1;
res.e--;
}
res.f <<= (kDiySignificandSize - kDpSignificandSize - 2);
res.e = res.e - (kDiySignificandSize - kDpSignificandSize - 2);
return res;
}
void NormalizedBoundaries(DiyFp* minus, DiyFp* plus) const {
DiyFp pl = DiyFp((f << 1) + 1, e - 1).NormalizeBoundary();
DiyFp mi = (f == kDpHiddenBit) ? DiyFp((f << 2) - 1, e - 2) : DiyFp((f << 1) - 1, e - 1);
mi.f <<= mi.e - pl.e;
mi.e = pl.e;
*plus = pl;
*minus = mi;
}
double ToDouble() const {
union {
double d;
uint64_t u64;
}u;
const uint64_t be = (e == kDpDenormalExponent && (f & kDpHiddenBit) == 0) ? 0 :
static_cast<uint64_t>(e + kDpExponentBias);
u.u64 = (f & kDpSignificandMask) | (be << kDpSignificandSize);
return u.d;
}
static const int kDiySignificandSize = 64;
static const int kDpSignificandSize = 52;
static const int kDpExponentBias = 0x3FF + kDpSignificandSize;
static const int kDpMaxExponent = 0x7FF - kDpExponentBias;
static const int kDpMinExponent = -kDpExponentBias;
static const int kDpDenormalExponent = -kDpExponentBias + 1;
static const uint64_t kDpExponentMask = RAPIDJSON_UINT64_C2(0x7FF00000, 0x00000000);
static const uint64_t kDpSignificandMask = RAPIDJSON_UINT64_C2(0x000FFFFF, 0xFFFFFFFF);
static const uint64_t kDpHiddenBit = RAPIDJSON_UINT64_C2(0x00100000, 0x00000000);
uint64_t f;
int e;
};
inline DiyFp GetCachedPowerByIndex(size_t index) {
// 10^-348, 10^-340, ..., 10^340
static const uint64_t kCachedPowers_F[] = {
RAPIDJSON_UINT64_C2(0xfa8fd5a0, 0x081c0288), RAPIDJSON_UINT64_C2(0xbaaee17f, 0xa23ebf76),
RAPIDJSON_UINT64_C2(0x8b16fb20, 0x3055ac76), RAPIDJSON_UINT64_C2(0xcf42894a, 0x5dce35ea),
RAPIDJSON_UINT64_C2(0x9a6bb0aa, 0x55653b2d), RAPIDJSON_UINT64_C2(0xe61acf03, 0x3d1a45df),
RAPIDJSON_UINT64_C2(0xab70fe17, 0xc79ac6ca), RAPIDJSON_UINT64_C2(0xff77b1fc, 0xbebcdc4f),
RAPIDJSON_UINT64_C2(0xbe5691ef, 0x416bd60c), RAPIDJSON_UINT64_C2(0x8dd01fad, 0x907ffc3c),
RAPIDJSON_UINT64_C2(0xd3515c28, 0x31559a83), RAPIDJSON_UINT64_C2(0x9d71ac8f, 0xada6c9b5),
RAPIDJSON_UINT64_C2(0xea9c2277, 0x23ee8bcb), RAPIDJSON_UINT64_C2(0xaecc4991, 0x4078536d),
RAPIDJSON_UINT64_C2(0x823c1279, 0x5db6ce57), RAPIDJSON_UINT64_C2(0xc2109436, 0x4dfb5637),
RAPIDJSON_UINT64_C2(0x9096ea6f, 0x3848984f), RAPIDJSON_UINT64_C2(0xd77485cb, 0x25823ac7),
RAPIDJSON_UINT64_C2(0xa086cfcd, 0x97bf97f4), RAPIDJSON_UINT64_C2(0xef340a98, 0x172aace5),
RAPIDJSON_UINT64_C2(0xb23867fb, 0x2a35b28e), RAPIDJSON_UINT64_C2(0x84c8d4df, 0xd2c63f3b),
RAPIDJSON_UINT64_C2(0xc5dd4427, 0x1ad3cdba), RAPIDJSON_UINT64_C2(0x936b9fce, 0xbb25c996),
RAPIDJSON_UINT64_C2(0xdbac6c24, 0x7d62a584), RAPIDJSON_UINT64_C2(0xa3ab6658, 0x0d5fdaf6),
RAPIDJSON_UINT64_C2(0xf3e2f893, 0xdec3f126), RAPIDJSON_UINT64_C2(0xb5b5ada8, 0xaaff80b8),
RAPIDJSON_UINT64_C2(0x87625f05, 0x6c7c4a8b), RAPIDJSON_UINT64_C2(0xc9bcff60, 0x34c13053),
RAPIDJSON_UINT64_C2(0x964e858c, 0x91ba2655), RAPIDJSON_UINT64_C2(0xdff97724, 0x70297ebd),
RAPIDJSON_UINT64_C2(0xa6dfbd9f, 0xb8e5b88f), RAPIDJSON_UINT64_C2(0xf8a95fcf, 0x88747d94),
RAPIDJSON_UINT64_C2(0xb9447093, 0x8fa89bcf), RAPIDJSON_UINT64_C2(0x8a08f0f8, 0xbf0f156b),
RAPIDJSON_UINT64_C2(0xcdb02555, 0x653131b6), RAPIDJSON_UINT64_C2(0x993fe2c6, 0xd07b7fac),
RAPIDJSON_UINT64_C2(0xe45c10c4, 0x2a2b3b06), RAPIDJSON_UINT64_C2(0xaa242499, 0x697392d3),
RAPIDJSON_UINT64_C2(0xfd87b5f2, 0x8300ca0e), RAPIDJSON_UINT64_C2(0xbce50864, 0x92111aeb),
RAPIDJSON_UINT64_C2(0x8cbccc09, 0x6f5088cc), RAPIDJSON_UINT64_C2(0xd1b71758, 0xe219652c),
RAPIDJSON_UINT64_C2(0x9c400000, 0x00000000), RAPIDJSON_UINT64_C2(0xe8d4a510, 0x00000000),
RAPIDJSON_UINT64_C2(0xad78ebc5, 0xac620000), RAPIDJSON_UINT64_C2(0x813f3978, 0xf8940984),
RAPIDJSON_UINT64_C2(0xc097ce7b, 0xc90715b3), RAPIDJSON_UINT64_C2(0x8f7e32ce, 0x7bea5c70),
RAPIDJSON_UINT64_C2(0xd5d238a4, 0xabe98068), RAPIDJSON_UINT64_C2(0x9f4f2726, 0x179a2245),
RAPIDJSON_UINT64_C2(0xed63a231, 0xd4c4fb27), RAPIDJSON_UINT64_C2(0xb0de6538, 0x8cc8ada8),
RAPIDJSON_UINT64_C2(0x83c7088e, 0x1aab65db), RAPIDJSON_UINT64_C2(0xc45d1df9, 0x42711d9a),
RAPIDJSON_UINT64_C2(0x924d692c, 0xa61be758), RAPIDJSON_UINT64_C2(0xda01ee64, 0x1a708dea),
RAPIDJSON_UINT64_C2(0xa26da399, 0x9aef774a), RAPIDJSON_UINT64_C2(0xf209787b, 0xb47d6b85),
RAPIDJSON_UINT64_C2(0xb454e4a1, 0x79dd1877), RAPIDJSON_UINT64_C2(0x865b8692, 0x5b9bc5c2),
RAPIDJSON_UINT64_C2(0xc83553c5, 0xc8965d3d), RAPIDJSON_UINT64_C2(0x952ab45c, 0xfa97a0b3),
RAPIDJSON_UINT64_C2(0xde469fbd, 0x99a05fe3), RAPIDJSON_UINT64_C2(0xa59bc234, 0xdb398c25),
RAPIDJSON_UINT64_C2(0xf6c69a72, 0xa3989f5c), RAPIDJSON_UINT64_C2(0xb7dcbf53, 0x54e9bece),
RAPIDJSON_UINT64_C2(0x88fcf317, 0xf22241e2), RAPIDJSON_UINT64_C2(0xcc20ce9b, 0xd35c78a5),
RAPIDJSON_UINT64_C2(0x98165af3, 0x7b2153df), RAPIDJSON_UINT64_C2(0xe2a0b5dc, 0x971f303a),
RAPIDJSON_UINT64_C2(0xa8d9d153, 0x5ce3b396), RAPIDJSON_UINT64_C2(0xfb9b7cd9, 0xa4a7443c),
RAPIDJSON_UINT64_C2(0xbb764c4c, 0xa7a44410), RAPIDJSON_UINT64_C2(0x8bab8eef, 0xb6409c1a),
RAPIDJSON_UINT64_C2(0xd01fef10, 0xa657842c), RAPIDJSON_UINT64_C2(0x9b10a4e5, 0xe9913129),
RAPIDJSON_UINT64_C2(0xe7109bfb, 0xa19c0c9d), RAPIDJSON_UINT64_C2(0xac2820d9, 0x623bf429),
RAPIDJSON_UINT64_C2(0x80444b5e, 0x7aa7cf85), RAPIDJSON_UINT64_C2(0xbf21e440, 0x03acdd2d),
RAPIDJSON_UINT64_C2(0x8e679c2f, 0x5e44ff8f), RAPIDJSON_UINT64_C2(0xd433179d, 0x9c8cb841),
RAPIDJSON_UINT64_C2(0x9e19db92, 0xb4e31ba9), RAPIDJSON_UINT64_C2(0xeb96bf6e, 0xbadf77d9),
RAPIDJSON_UINT64_C2(0xaf87023b, 0x9bf0ee6b)
};
static const int16_t kCachedPowers_E[] = {
-1220, -1193, -1166, -1140, -1113, -1087, -1060, -1034, -1007, -980,
-954, -927, -901, -874, -847, -821, -794, -768, -741, -715,
-688, -661, -635, -608, -582, -555, -529, -502, -475, -449,
-422, -396, -369, -343, -316, -289, -263, -236, -210, -183,
-157, -130, -103, -77, -50, -24, 3, 30, 56, 83,
109, 136, 162, 189, 216, 242, 269, 295, 322, 348,
375, 402, 428, 455, 481, 508, 534, 561, 588, 614,
641, 667, 694, 720, 747, 774, 800, 827, 853, 880,
907, 933, 960, 986, 1013, 1039, 1066
};
return DiyFp(kCachedPowers_F[index], kCachedPowers_E[index]);
}
inline DiyFp GetCachedPower(int e, int* K) {
//int k = static_cast<int>(ceil((-61 - e) * 0.30102999566398114)) + 374;
double dk = (-61 - e) * 0.30102999566398114 + 347; // dk must be positive, so can do ceiling in positive
int k = static_cast<int>(dk);
if (dk - k > 0.0)
k++;
unsigned index = static_cast<unsigned>((k >> 3) + 1);
*K = -(-348 + static_cast<int>(index << 3)); // decimal exponent no need lookup table
return GetCachedPowerByIndex(index);
}
inline DiyFp GetCachedPower10(int exp, int *outExp) {
unsigned index = (exp + 348) / 8;
*outExp = -348 + index * 8;
return GetCachedPowerByIndex(index);
}
#ifdef __GNUC__
RAPIDJSON_DIAG_POP
#endif
} // namespace internal
RAPIDJSON_NAMESPACE_END
#endif // RAPIDJSON_DIYFP_H_
+217
Ver Arquivo
@@ -0,0 +1,217 @@
// Tencent is pleased to support the open source community by making RapidJSON available.
//
// Copyright (C) 2015 THL A29 Limited, a Tencent company, and Milo Yip. All rights reserved.
//
// Licensed under the MIT License (the "License"); you may not use this file except
// in compliance with the License. You may obtain a copy of the License at
//
// http://opensource.org/licenses/MIT
//
// Unless required by applicable law or agreed to in writing, software distributed
// under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
// CONDITIONS OF ANY KIND, either express or implied. See the License for the
// specific language governing permissions and limitations under the License.
// This is a C++ header-only implementation of Grisu2 algorithm from the publication:
// Loitsch, Florian. "Printing floating-point numbers quickly and accurately with
// integers." ACM Sigplan Notices 45.6 (2010): 233-243.
#ifndef RAPIDJSON_DTOA_
#define RAPIDJSON_DTOA_
#include "itoa.h" // GetDigitsLut()
#include "diyfp.h"
#include "ieee754.h"
RAPIDJSON_NAMESPACE_BEGIN
namespace internal {
#ifdef __GNUC__
RAPIDJSON_DIAG_PUSH
RAPIDJSON_DIAG_OFF(effc++)
#endif
inline void GrisuRound(char* buffer, int len, uint64_t delta, uint64_t rest, uint64_t ten_kappa, uint64_t wp_w) {
while (rest < wp_w && delta - rest >= ten_kappa &&
(rest + ten_kappa < wp_w || /// closer
wp_w - rest > rest + ten_kappa - wp_w)) {
buffer[len - 1]--;
rest += ten_kappa;
}
}
inline unsigned CountDecimalDigit32(uint32_t n) {
// Simple pure C++ implementation was faster than __builtin_clz version in this situation.
if (n < 10) return 1;
if (n < 100) return 2;
if (n < 1000) return 3;
if (n < 10000) return 4;
if (n < 100000) return 5;
if (n < 1000000) return 6;
if (n < 10000000) return 7;
if (n < 100000000) return 8;
// Will not reach 10 digits in DigitGen()
//if (n < 1000000000) return 9;
//return 10;
return 9;
}
inline void DigitGen(const DiyFp& W, const DiyFp& Mp, uint64_t delta, char* buffer, int* len, int* K) {
static const uint32_t kPow10[] = { 1, 10, 100, 1000, 10000, 100000, 1000000, 10000000, 100000000, 1000000000 };
const DiyFp one(uint64_t(1) << -Mp.e, Mp.e);
const DiyFp wp_w = Mp - W;
uint32_t p1 = static_cast<uint32_t>(Mp.f >> -one.e);
uint64_t p2 = Mp.f & (one.f - 1);
int kappa = CountDecimalDigit32(p1); // kappa in [0, 9]
*len = 0;
while (kappa > 0) {
uint32_t d = 0;
switch (kappa) {
case 9: d = p1 / 100000000; p1 %= 100000000; break;
case 8: d = p1 / 10000000; p1 %= 10000000; break;
case 7: d = p1 / 1000000; p1 %= 1000000; break;
case 6: d = p1 / 100000; p1 %= 100000; break;
case 5: d = p1 / 10000; p1 %= 10000; break;
case 4: d = p1 / 1000; p1 %= 1000; break;
case 3: d = p1 / 100; p1 %= 100; break;
case 2: d = p1 / 10; p1 %= 10; break;
case 1: d = p1; p1 = 0; break;
default:;
}
if (d || *len)
buffer[(*len)++] = static_cast<char>('0' + static_cast<char>(d));
kappa--;
uint64_t tmp = (static_cast<uint64_t>(p1) << -one.e) + p2;
if (tmp <= delta) {
*K += kappa;
GrisuRound(buffer, *len, delta, tmp, static_cast<uint64_t>(kPow10[kappa]) << -one.e, wp_w.f);
return;
}
}
// kappa = 0
for (;;) {
p2 *= 10;
delta *= 10;
char d = static_cast<char>(p2 >> -one.e);
if (d || *len)
buffer[(*len)++] = static_cast<char>('0' + d);
p2 &= one.f - 1;
kappa--;
if (p2 < delta) {
*K += kappa;
GrisuRound(buffer, *len, delta, p2, one.f, wp_w.f * kPow10[-kappa]);
return;
}
}
}
inline void Grisu2(double value, char* buffer, int* length, int* K) {
const DiyFp v(value);
DiyFp w_m, w_p;
v.NormalizedBoundaries(&w_m, &w_p);
const DiyFp c_mk = GetCachedPower(w_p.e, K);
const DiyFp W = v.Normalize() * c_mk;
DiyFp Wp = w_p * c_mk;
DiyFp Wm = w_m * c_mk;
Wm.f++;
Wp.f--;
DigitGen(W, Wp, Wp.f - Wm.f, buffer, length, K);
}
inline char* WriteExponent(int K, char* buffer) {
if (K < 0) {
*buffer++ = '-';
K = -K;
}
if (K >= 100) {
*buffer++ = static_cast<char>('0' + static_cast<char>(K / 100));
K %= 100;
const char* d = GetDigitsLut() + K * 2;
*buffer++ = d[0];
*buffer++ = d[1];
}
else if (K >= 10) {
const char* d = GetDigitsLut() + K * 2;
*buffer++ = d[0];
*buffer++ = d[1];
}
else
*buffer++ = static_cast<char>('0' + static_cast<char>(K));
return buffer;
}
inline char* Prettify(char* buffer, int length, int k) {
const int kk = length + k; // 10^(kk-1) <= v < 10^kk
if (length <= kk && kk <= 21) {
// 1234e7 -> 12340000000
for (int i = length; i < kk; i++)
buffer[i] = '0';
buffer[kk] = '.';
buffer[kk + 1] = '0';
return &buffer[kk + 2];
}
else if (0 < kk && kk <= 21) {
// 1234e-2 -> 12.34
std::memmove(&buffer[kk + 1], &buffer[kk], length - kk);
buffer[kk] = '.';
return &buffer[length + 1];
}
else if (-6 < kk && kk <= 0) {
// 1234e-6 -> 0.001234
const int offset = 2 - kk;
std::memmove(&buffer[offset], &buffer[0], length);
buffer[0] = '0';
buffer[1] = '.';
for (int i = 2; i < offset; i++)
buffer[i] = '0';
return &buffer[length + offset];
}
else if (length == 1) {
// 1e30
buffer[1] = 'e';
return WriteExponent(kk - 1, &buffer[2]);
}
else {
// 1234e30 -> 1.234e33
std::memmove(&buffer[2], &buffer[1], length - 1);
buffer[1] = '.';
buffer[length + 1] = 'e';
return WriteExponent(kk - 1, &buffer[0 + length + 2]);
}
}
inline char* dtoa(double value, char* buffer) {
Double d(value);
if (d.IsZero()) {
if (d.Sign())
*buffer++ = '-'; // -0.0, Issue #289
buffer[0] = '0';
buffer[1] = '.';
buffer[2] = '0';
return &buffer[3];
}
else {
if (value < 0) {
*buffer++ = '-';
value = -value;
}
int length, K;
Grisu2(value, buffer, &length, &K);
return Prettify(buffer, length, K);
}
}
#ifdef __GNUC__
RAPIDJSON_DIAG_POP
#endif
} // namespace internal
RAPIDJSON_NAMESPACE_END
#endif // RAPIDJSON_DTOA_
+77
Ver Arquivo
@@ -0,0 +1,77 @@
// Tencent is pleased to support the open source community by making RapidJSON available.
//
// Copyright (C) 2015 THL A29 Limited, a Tencent company, and Milo Yip. All rights reserved.
//
// Licensed under the MIT License (the "License"); you may not use this file except
// in compliance with the License. You may obtain a copy of the License at
//
// http://opensource.org/licenses/MIT
//
// Unless required by applicable law or agreed to in writing, software distributed
// under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
// CONDITIONS OF ANY KIND, either express or implied. See the License for the
// specific language governing permissions and limitations under the License.
#ifndef RAPIDJSON_IEEE754_
#define RAPIDJSON_IEEE754_
#include "../rapidjson.h"
RAPIDJSON_NAMESPACE_BEGIN
namespace internal {
class Double {
public:
Double() {}
Double(double d) : d(d) {}
Double(uint64_t u) : u(u) {}
double Value() const { return d; }
uint64_t Uint64Value() const { return u; }
double NextPositiveDouble() const {
RAPIDJSON_ASSERT(!Sign());
return Double(u + 1).Value();
}
bool Sign() const { return (u & kSignMask) != 0; }
uint64_t Significand() const { return u & kSignificandMask; }
int Exponent() const { return ((u & kExponentMask) >> kSignificandSize) - kExponentBias; }
bool IsNan() const { return (u & kExponentMask) == kExponentMask && Significand() != 0; }
bool IsInf() const { return (u & kExponentMask) == kExponentMask && Significand() == 0; }
bool IsNormal() const { return (u & kExponentMask) != 0 || Significand() == 0; }
bool IsZero() const { return (u & (kExponentMask | kSignificandMask)) == 0; }
uint64_t IntegerSignificand() const { return IsNormal() ? Significand() | kHiddenBit : Significand(); }
int IntegerExponent() const { return (IsNormal() ? Exponent() : kDenormalExponent) - kSignificandSize; }
uint64_t ToBias() const { return (u & kSignMask) ? ~u + 1 : u | kSignMask; }
static unsigned EffectiveSignificandSize(int order) {
if (order >= -1021)
return 53;
else if (order <= -1074)
return 0;
else
return order + 1074;
}
private:
static const int kSignificandSize = 52;
static const int kExponentBias = 0x3FF;
static const int kDenormalExponent = 1 - kExponentBias;
static const uint64_t kSignMask = RAPIDJSON_UINT64_C2(0x80000000, 0x00000000);
static const uint64_t kExponentMask = RAPIDJSON_UINT64_C2(0x7FF00000, 0x00000000);
static const uint64_t kSignificandMask = RAPIDJSON_UINT64_C2(0x000FFFFF, 0xFFFFFFFF);
static const uint64_t kHiddenBit = RAPIDJSON_UINT64_C2(0x00100000, 0x00000000);
union {
double d;
uint64_t u;
};
};
} // namespace internal
RAPIDJSON_NAMESPACE_END
#endif // RAPIDJSON_IEEE754_
+304
Ver Arquivo
@@ -0,0 +1,304 @@
// Tencent is pleased to support the open source community by making RapidJSON available.
//
// Copyright (C) 2015 THL A29 Limited, a Tencent company, and Milo Yip. All rights reserved.
//
// Licensed under the MIT License (the "License"); you may not use this file except
// in compliance with the License. You may obtain a copy of the License at
//
// http://opensource.org/licenses/MIT
//
// Unless required by applicable law or agreed to in writing, software distributed
// under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
// CONDITIONS OF ANY KIND, either express or implied. See the License for the
// specific language governing permissions and limitations under the License.
#ifndef RAPIDJSON_ITOA_
#define RAPIDJSON_ITOA_
#include "../rapidjson.h"
RAPIDJSON_NAMESPACE_BEGIN
namespace internal {
inline const char* GetDigitsLut() {
static const char cDigitsLut[200] = {
'0','0','0','1','0','2','0','3','0','4','0','5','0','6','0','7','0','8','0','9',
'1','0','1','1','1','2','1','3','1','4','1','5','1','6','1','7','1','8','1','9',
'2','0','2','1','2','2','2','3','2','4','2','5','2','6','2','7','2','8','2','9',
'3','0','3','1','3','2','3','3','3','4','3','5','3','6','3','7','3','8','3','9',
'4','0','4','1','4','2','4','3','4','4','4','5','4','6','4','7','4','8','4','9',
'5','0','5','1','5','2','5','3','5','4','5','5','5','6','5','7','5','8','5','9',
'6','0','6','1','6','2','6','3','6','4','6','5','6','6','6','7','6','8','6','9',
'7','0','7','1','7','2','7','3','7','4','7','5','7','6','7','7','7','8','7','9',
'8','0','8','1','8','2','8','3','8','4','8','5','8','6','8','7','8','8','8','9',
'9','0','9','1','9','2','9','3','9','4','9','5','9','6','9','7','9','8','9','9'
};
return cDigitsLut;
}
inline char* u32toa(uint32_t value, char* buffer) {
const char* cDigitsLut = GetDigitsLut();
if (value < 10000) {
const uint32_t d1 = (value / 100) << 1;
const uint32_t d2 = (value % 100) << 1;
if (value >= 1000)
*buffer++ = cDigitsLut[d1];
if (value >= 100)
*buffer++ = cDigitsLut[d1 + 1];
if (value >= 10)
*buffer++ = cDigitsLut[d2];
*buffer++ = cDigitsLut[d2 + 1];
}
else if (value < 100000000) {
// value = bbbbcccc
const uint32_t b = value / 10000;
const uint32_t c = value % 10000;
const uint32_t d1 = (b / 100) << 1;
const uint32_t d2 = (b % 100) << 1;
const uint32_t d3 = (c / 100) << 1;
const uint32_t d4 = (c % 100) << 1;
if (value >= 10000000)
*buffer++ = cDigitsLut[d1];
if (value >= 1000000)
*buffer++ = cDigitsLut[d1 + 1];
if (value >= 100000)
*buffer++ = cDigitsLut[d2];
*buffer++ = cDigitsLut[d2 + 1];
*buffer++ = cDigitsLut[d3];
*buffer++ = cDigitsLut[d3 + 1];
*buffer++ = cDigitsLut[d4];
*buffer++ = cDigitsLut[d4 + 1];
}
else {
// value = aabbbbcccc in decimal
const uint32_t a = value / 100000000; // 1 to 42
value %= 100000000;
if (a >= 10) {
const unsigned i = a << 1;
*buffer++ = cDigitsLut[i];
*buffer++ = cDigitsLut[i + 1];
}
else
*buffer++ = static_cast<char>('0' + static_cast<char>(a));
const uint32_t b = value / 10000; // 0 to 9999
const uint32_t c = value % 10000; // 0 to 9999
const uint32_t d1 = (b / 100) << 1;
const uint32_t d2 = (b % 100) << 1;
const uint32_t d3 = (c / 100) << 1;
const uint32_t d4 = (c % 100) << 1;
*buffer++ = cDigitsLut[d1];
*buffer++ = cDigitsLut[d1 + 1];
*buffer++ = cDigitsLut[d2];
*buffer++ = cDigitsLut[d2 + 1];
*buffer++ = cDigitsLut[d3];
*buffer++ = cDigitsLut[d3 + 1];
*buffer++ = cDigitsLut[d4];
*buffer++ = cDigitsLut[d4 + 1];
}
return buffer;
}
inline char* i32toa(int32_t value, char* buffer) {
uint32_t u = static_cast<uint32_t>(value);
if (value < 0) {
*buffer++ = '-';
u = ~u + 1;
}
return u32toa(u, buffer);
}
inline char* u64toa(uint64_t value, char* buffer) {
const char* cDigitsLut = GetDigitsLut();
const uint64_t kTen8 = 100000000;
const uint64_t kTen9 = kTen8 * 10;
const uint64_t kTen10 = kTen8 * 100;
const uint64_t kTen11 = kTen8 * 1000;
const uint64_t kTen12 = kTen8 * 10000;
const uint64_t kTen13 = kTen8 * 100000;
const uint64_t kTen14 = kTen8 * 1000000;
const uint64_t kTen15 = kTen8 * 10000000;
const uint64_t kTen16 = kTen8 * kTen8;
if (value < kTen8) {
uint32_t v = static_cast<uint32_t>(value);
if (v < 10000) {
const uint32_t d1 = (v / 100) << 1;
const uint32_t d2 = (v % 100) << 1;
if (v >= 1000)
*buffer++ = cDigitsLut[d1];
if (v >= 100)
*buffer++ = cDigitsLut[d1 + 1];
if (v >= 10)
*buffer++ = cDigitsLut[d2];
*buffer++ = cDigitsLut[d2 + 1];
}
else {
// value = bbbbcccc
const uint32_t b = v / 10000;
const uint32_t c = v % 10000;
const uint32_t d1 = (b / 100) << 1;
const uint32_t d2 = (b % 100) << 1;
const uint32_t d3 = (c / 100) << 1;
const uint32_t d4 = (c % 100) << 1;
if (value >= 10000000)
*buffer++ = cDigitsLut[d1];
if (value >= 1000000)
*buffer++ = cDigitsLut[d1 + 1];
if (value >= 100000)
*buffer++ = cDigitsLut[d2];
*buffer++ = cDigitsLut[d2 + 1];
*buffer++ = cDigitsLut[d3];
*buffer++ = cDigitsLut[d3 + 1];
*buffer++ = cDigitsLut[d4];
*buffer++ = cDigitsLut[d4 + 1];
}
}
else if (value < kTen16) {
const uint32_t v0 = static_cast<uint32_t>(value / kTen8);
const uint32_t v1 = static_cast<uint32_t>(value % kTen8);
const uint32_t b0 = v0 / 10000;
const uint32_t c0 = v0 % 10000;
const uint32_t d1 = (b0 / 100) << 1;
const uint32_t d2 = (b0 % 100) << 1;
const uint32_t d3 = (c0 / 100) << 1;
const uint32_t d4 = (c0 % 100) << 1;
const uint32_t b1 = v1 / 10000;
const uint32_t c1 = v1 % 10000;
const uint32_t d5 = (b1 / 100) << 1;
const uint32_t d6 = (b1 % 100) << 1;
const uint32_t d7 = (c1 / 100) << 1;
const uint32_t d8 = (c1 % 100) << 1;
if (value >= kTen15)
*buffer++ = cDigitsLut[d1];
if (value >= kTen14)
*buffer++ = cDigitsLut[d1 + 1];
if (value >= kTen13)
*buffer++ = cDigitsLut[d2];
if (value >= kTen12)
*buffer++ = cDigitsLut[d2 + 1];
if (value >= kTen11)
*buffer++ = cDigitsLut[d3];
if (value >= kTen10)
*buffer++ = cDigitsLut[d3 + 1];
if (value >= kTen9)
*buffer++ = cDigitsLut[d4];
if (value >= kTen8)
*buffer++ = cDigitsLut[d4 + 1];
*buffer++ = cDigitsLut[d5];
*buffer++ = cDigitsLut[d5 + 1];
*buffer++ = cDigitsLut[d6];
*buffer++ = cDigitsLut[d6 + 1];
*buffer++ = cDigitsLut[d7];
*buffer++ = cDigitsLut[d7 + 1];
*buffer++ = cDigitsLut[d8];
*buffer++ = cDigitsLut[d8 + 1];
}
else {
const uint32_t a = static_cast<uint32_t>(value / kTen16); // 1 to 1844
value %= kTen16;
if (a < 10)
*buffer++ = static_cast<char>('0' + static_cast<char>(a));
else if (a < 100) {
const uint32_t i = a << 1;
*buffer++ = cDigitsLut[i];
*buffer++ = cDigitsLut[i + 1];
}
else if (a < 1000) {
*buffer++ = static_cast<char>('0' + static_cast<char>(a / 100));
const uint32_t i = (a % 100) << 1;
*buffer++ = cDigitsLut[i];
*buffer++ = cDigitsLut[i + 1];
}
else {
const uint32_t i = (a / 100) << 1;
const uint32_t j = (a % 100) << 1;
*buffer++ = cDigitsLut[i];
*buffer++ = cDigitsLut[i + 1];
*buffer++ = cDigitsLut[j];
*buffer++ = cDigitsLut[j + 1];
}
const uint32_t v0 = static_cast<uint32_t>(value / kTen8);
const uint32_t v1 = static_cast<uint32_t>(value % kTen8);
const uint32_t b0 = v0 / 10000;
const uint32_t c0 = v0 % 10000;
const uint32_t d1 = (b0 / 100) << 1;
const uint32_t d2 = (b0 % 100) << 1;
const uint32_t d3 = (c0 / 100) << 1;
const uint32_t d4 = (c0 % 100) << 1;
const uint32_t b1 = v1 / 10000;
const uint32_t c1 = v1 % 10000;
const uint32_t d5 = (b1 / 100) << 1;
const uint32_t d6 = (b1 % 100) << 1;
const uint32_t d7 = (c1 / 100) << 1;
const uint32_t d8 = (c1 % 100) << 1;
*buffer++ = cDigitsLut[d1];
*buffer++ = cDigitsLut[d1 + 1];
*buffer++ = cDigitsLut[d2];
*buffer++ = cDigitsLut[d2 + 1];
*buffer++ = cDigitsLut[d3];
*buffer++ = cDigitsLut[d3 + 1];
*buffer++ = cDigitsLut[d4];
*buffer++ = cDigitsLut[d4 + 1];
*buffer++ = cDigitsLut[d5];
*buffer++ = cDigitsLut[d5 + 1];
*buffer++ = cDigitsLut[d6];
*buffer++ = cDigitsLut[d6 + 1];
*buffer++ = cDigitsLut[d7];
*buffer++ = cDigitsLut[d7 + 1];
*buffer++ = cDigitsLut[d8];
*buffer++ = cDigitsLut[d8 + 1];
}
return buffer;
}
inline char* i64toa(int64_t value, char* buffer) {
uint64_t u = static_cast<uint64_t>(value);
if (value < 0) {
*buffer++ = '-';
u = ~u + 1;
}
return u64toa(u, buffer);
}
} // namespace internal
RAPIDJSON_NAMESPACE_END
#endif // RAPIDJSON_ITOA_
+183
Ver Arquivo
@@ -0,0 +1,183 @@
// Tencent is pleased to support the open source community by making RapidJSON available.
//
// Copyright (C) 2015 THL A29 Limited, a Tencent company, and Milo Yip. All rights reserved.
//
// Licensed under the MIT License (the "License"); you may not use this file except
// in compliance with the License. You may obtain a copy of the License at
//
// http://opensource.org/licenses/MIT
//
// Unless required by applicable law or agreed to in writing, software distributed
// under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
// CONDITIONS OF ANY KIND, either express or implied. See the License for the
// specific language governing permissions and limitations under the License.
#ifndef RAPIDJSON_INTERNAL_META_H_
#define RAPIDJSON_INTERNAL_META_H_
#ifndef RAPIDJSON_RAPIDJSON_H_
#error <rapidjson.h> not yet included. Do not include this file directly.
#endif
#ifdef __GNUC__
RAPIDJSON_DIAG_PUSH
RAPIDJSON_DIAG_OFF(effc++)
#endif
#if defined(_MSC_VER)
RAPIDJSON_DIAG_PUSH
RAPIDJSON_DIAG_OFF(6334)
#endif
#if RAPIDJSON_HAS_CXX11_TYPETRAITS
#include <type_traits>
#endif
//@cond RAPIDJSON_INTERNAL
RAPIDJSON_NAMESPACE_BEGIN
namespace internal {
// Helper to wrap/convert arbitrary types to void, useful for arbitrary type matching
template <typename T> struct Void { typedef void Type; };
///////////////////////////////////////////////////////////////////////////////
// BoolType, TrueType, FalseType
//
template <bool Cond> struct BoolType {
static const bool Value = Cond;
typedef BoolType Type;
};
typedef BoolType<true> TrueType;
typedef BoolType<false> FalseType;
///////////////////////////////////////////////////////////////////////////////
// SelectIf, BoolExpr, NotExpr, AndExpr, OrExpr
//
template <bool C> struct SelectIfImpl { template <typename T1, typename T2> struct Apply { typedef T1 Type; }; };
template <> struct SelectIfImpl<false> { template <typename T1, typename T2> struct Apply { typedef T2 Type; }; };
template <bool C, typename T1, typename T2> struct SelectIfCond : SelectIfImpl<C>::template Apply<T1,T2> {};
template <typename C, typename T1, typename T2> struct SelectIf : SelectIfCond<C::Value, T1, T2> {};
template <bool Cond1, bool Cond2> struct AndExprCond : FalseType {};
template <> struct AndExprCond<true, true> : TrueType {};
template <bool Cond1, bool Cond2> struct OrExprCond : TrueType {};
template <> struct OrExprCond<false, false> : FalseType {};
template <typename C> struct BoolExpr : SelectIf<C,TrueType,FalseType>::Type {};
template <typename C> struct NotExpr : SelectIf<C,FalseType,TrueType>::Type {};
template <typename C1, typename C2> struct AndExpr : AndExprCond<C1::Value, C2::Value>::Type {};
template <typename C1, typename C2> struct OrExpr : OrExprCond<C1::Value, C2::Value>::Type {};
///////////////////////////////////////////////////////////////////////////////
// AddConst, MaybeAddConst, RemoveConst
template <typename T> struct AddConst { typedef const T Type; };
template <bool Constify, typename T> struct MaybeAddConst : SelectIfCond<Constify, const T, T> {};
template <typename T> struct RemoveConst { typedef T Type; };
template <typename T> struct RemoveConst<const T> { typedef T Type; };
///////////////////////////////////////////////////////////////////////////////
// IsSame, IsConst, IsMoreConst, IsPointer
//
template <typename T, typename U> struct IsSame : FalseType {};
template <typename T> struct IsSame<T, T> : TrueType {};
template <typename T> struct IsConst : FalseType {};
template <typename T> struct IsConst<const T> : TrueType {};
template <typename CT, typename T>
struct IsMoreConst
: AndExpr<IsSame<typename RemoveConst<CT>::Type, typename RemoveConst<T>::Type>,
BoolType<IsConst<CT>::Value >= IsConst<T>::Value> >::Type {};
template <typename T> struct IsPointer : FalseType {};
template <typename T> struct IsPointer<T*> : TrueType {};
///////////////////////////////////////////////////////////////////////////////
// IsBaseOf
//
#if RAPIDJSON_HAS_CXX11_TYPETRAITS
template <typename B, typename D> struct IsBaseOf
: BoolType< ::std::is_base_of<B,D>::value> {};
#else // simplified version adopted from Boost
template<typename B, typename D> struct IsBaseOfImpl {
RAPIDJSON_STATIC_ASSERT(sizeof(B) != 0);
RAPIDJSON_STATIC_ASSERT(sizeof(D) != 0);
typedef char (&Yes)[1];
typedef char (&No) [2];
template <typename T>
static Yes Check(const D*, T);
static No Check(const B*, int);
struct Host {
operator const B*() const;
operator const D*();
};
enum { Value = (sizeof(Check(Host(), 0)) == sizeof(Yes)) };
};
template <typename B, typename D> struct IsBaseOf
: OrExpr<IsSame<B, D>, BoolExpr<IsBaseOfImpl<B, D> > >::Type {};
#endif // RAPIDJSON_HAS_CXX11_TYPETRAITS
//////////////////////////////////////////////////////////////////////////
// EnableIf / DisableIf
//
template <bool Condition, typename T = void> struct EnableIfCond { typedef T Type; };
template <typename T> struct EnableIfCond<false, T> { /* empty */ };
template <bool Condition, typename T = void> struct DisableIfCond { typedef T Type; };
template <typename T> struct DisableIfCond<true, T> { /* empty */ };
template <typename Condition, typename T = void>
struct EnableIf : EnableIfCond<Condition::Value, T> {};
template <typename Condition, typename T = void>
struct DisableIf : DisableIfCond<Condition::Value, T> {};
// SFINAE helpers
struct SfinaeTag {};
template <typename T> struct RemoveSfinaeTag;
template <typename T> struct RemoveSfinaeTag<SfinaeTag&(*)(T)> { typedef T Type; };
#define RAPIDJSON_REMOVEFPTR_(type) \
typename ::RAPIDJSON_NAMESPACE::internal::RemoveSfinaeTag \
< ::RAPIDJSON_NAMESPACE::internal::SfinaeTag&(*) type>::Type
#define RAPIDJSON_ENABLEIF(cond) \
typename ::RAPIDJSON_NAMESPACE::internal::EnableIf \
<RAPIDJSON_REMOVEFPTR_(cond)>::Type * = NULL
#define RAPIDJSON_DISABLEIF(cond) \
typename ::RAPIDJSON_NAMESPACE::internal::DisableIf \
<RAPIDJSON_REMOVEFPTR_(cond)>::Type * = NULL
#define RAPIDJSON_ENABLEIF_RETURN(cond,returntype) \
typename ::RAPIDJSON_NAMESPACE::internal::EnableIf \
<RAPIDJSON_REMOVEFPTR_(cond), \
RAPIDJSON_REMOVEFPTR_(returntype)>::Type
#define RAPIDJSON_DISABLEIF_RETURN(cond,returntype) \
typename ::RAPIDJSON_NAMESPACE::internal::DisableIf \
<RAPIDJSON_REMOVEFPTR_(cond), \
RAPIDJSON_REMOVEFPTR_(returntype)>::Type
} // namespace internal
RAPIDJSON_NAMESPACE_END
//@endcond
#if defined(__GNUC__) || defined(_MSC_VER)
RAPIDJSON_DIAG_POP
#endif
#endif // RAPIDJSON_INTERNAL_META_H_
+53
Ver Arquivo
@@ -0,0 +1,53 @@
// Tencent is pleased to support the open source community by making RapidJSON available.
//
// Copyright (C) 2015 THL A29 Limited, a Tencent company, and Milo Yip. All rights reserved.
//
// Licensed under the MIT License (the "License"); you may not use this file except
// in compliance with the License. You may obtain a copy of the License at
//
// http://opensource.org/licenses/MIT
//
// Unless required by applicable law or agreed to in writing, software distributed
// under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
// CONDITIONS OF ANY KIND, either express or implied. See the License for the
// specific language governing permissions and limitations under the License.
#ifndef RAPIDJSON_POW10_
#define RAPIDJSON_POW10_
RAPIDJSON_NAMESPACE_BEGIN
namespace internal {
//! Computes integer powers of 10 in double (10.0^n).
/*! This function uses lookup table for fast and accurate results.
\param n non-negative exponent. Must <= 308.
\return 10.0^n
*/
inline double Pow10(int n) {
static const double e[] = { // 1e-0...1e308: 309 * 8 bytes = 2472 bytes
1e+0,
1e+1, 1e+2, 1e+3, 1e+4, 1e+5, 1e+6, 1e+7, 1e+8, 1e+9, 1e+10, 1e+11, 1e+12, 1e+13, 1e+14, 1e+15, 1e+16, 1e+17, 1e+18, 1e+19, 1e+20,
1e+21, 1e+22, 1e+23, 1e+24, 1e+25, 1e+26, 1e+27, 1e+28, 1e+29, 1e+30, 1e+31, 1e+32, 1e+33, 1e+34, 1e+35, 1e+36, 1e+37, 1e+38, 1e+39, 1e+40,
1e+41, 1e+42, 1e+43, 1e+44, 1e+45, 1e+46, 1e+47, 1e+48, 1e+49, 1e+50, 1e+51, 1e+52, 1e+53, 1e+54, 1e+55, 1e+56, 1e+57, 1e+58, 1e+59, 1e+60,
1e+61, 1e+62, 1e+63, 1e+64, 1e+65, 1e+66, 1e+67, 1e+68, 1e+69, 1e+70, 1e+71, 1e+72, 1e+73, 1e+74, 1e+75, 1e+76, 1e+77, 1e+78, 1e+79, 1e+80,
1e+81, 1e+82, 1e+83, 1e+84, 1e+85, 1e+86, 1e+87, 1e+88, 1e+89, 1e+90, 1e+91, 1e+92, 1e+93, 1e+94, 1e+95, 1e+96, 1e+97, 1e+98, 1e+99, 1e+100,
1e+101,1e+102,1e+103,1e+104,1e+105,1e+106,1e+107,1e+108,1e+109,1e+110,1e+111,1e+112,1e+113,1e+114,1e+115,1e+116,1e+117,1e+118,1e+119,1e+120,
1e+121,1e+122,1e+123,1e+124,1e+125,1e+126,1e+127,1e+128,1e+129,1e+130,1e+131,1e+132,1e+133,1e+134,1e+135,1e+136,1e+137,1e+138,1e+139,1e+140,
1e+141,1e+142,1e+143,1e+144,1e+145,1e+146,1e+147,1e+148,1e+149,1e+150,1e+151,1e+152,1e+153,1e+154,1e+155,1e+156,1e+157,1e+158,1e+159,1e+160,
1e+161,1e+162,1e+163,1e+164,1e+165,1e+166,1e+167,1e+168,1e+169,1e+170,1e+171,1e+172,1e+173,1e+174,1e+175,1e+176,1e+177,1e+178,1e+179,1e+180,
1e+181,1e+182,1e+183,1e+184,1e+185,1e+186,1e+187,1e+188,1e+189,1e+190,1e+191,1e+192,1e+193,1e+194,1e+195,1e+196,1e+197,1e+198,1e+199,1e+200,
1e+201,1e+202,1e+203,1e+204,1e+205,1e+206,1e+207,1e+208,1e+209,1e+210,1e+211,1e+212,1e+213,1e+214,1e+215,1e+216,1e+217,1e+218,1e+219,1e+220,
1e+221,1e+222,1e+223,1e+224,1e+225,1e+226,1e+227,1e+228,1e+229,1e+230,1e+231,1e+232,1e+233,1e+234,1e+235,1e+236,1e+237,1e+238,1e+239,1e+240,
1e+241,1e+242,1e+243,1e+244,1e+245,1e+246,1e+247,1e+248,1e+249,1e+250,1e+251,1e+252,1e+253,1e+254,1e+255,1e+256,1e+257,1e+258,1e+259,1e+260,
1e+261,1e+262,1e+263,1e+264,1e+265,1e+266,1e+267,1e+268,1e+269,1e+270,1e+271,1e+272,1e+273,1e+274,1e+275,1e+276,1e+277,1e+278,1e+279,1e+280,
1e+281,1e+282,1e+283,1e+284,1e+285,1e+286,1e+287,1e+288,1e+289,1e+290,1e+291,1e+292,1e+293,1e+294,1e+295,1e+296,1e+297,1e+298,1e+299,1e+300,
1e+301,1e+302,1e+303,1e+304,1e+305,1e+306,1e+307,1e+308
};
RAPIDJSON_ASSERT(n >= 0 && n <= 308);
return e[n];
}
} // namespace internal
RAPIDJSON_NAMESPACE_END
#endif // RAPIDJSON_POW10_
+177
Ver Arquivo
@@ -0,0 +1,177 @@
// Tencent is pleased to support the open source community by making RapidJSON available.
//
// Copyright (C) 2015 THL A29 Limited, a Tencent company, and Milo Yip. All rights reserved.
//
// Licensed under the MIT License (the "License"); you may not use this file except
// in compliance with the License. You may obtain a copy of the License at
//
// http://opensource.org/licenses/MIT
//
// Unless required by applicable law or agreed to in writing, software distributed
// under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
// CONDITIONS OF ANY KIND, either express or implied. See the License for the
// specific language governing permissions and limitations under the License.
#ifndef RAPIDJSON_INTERNAL_STACK_H_
#define RAPIDJSON_INTERNAL_STACK_H_
RAPIDJSON_NAMESPACE_BEGIN
namespace internal {
///////////////////////////////////////////////////////////////////////////////
// Stack
//! A type-unsafe stack for storing different types of data.
/*! \tparam Allocator Allocator for allocating stack memory.
*/
template <typename Allocator>
class Stack {
public:
// Optimization note: Do not allocate memory for stack_ in constructor.
// Do it lazily when first Push() -> Expand() -> Resize().
Stack(Allocator* allocator, size_t stackCapacity) : allocator_(allocator), ownAllocator_(0), stack_(0), stackTop_(0), stackEnd_(0), initialCapacity_(stackCapacity) {
RAPIDJSON_ASSERT(stackCapacity > 0);
}
#if RAPIDJSON_HAS_CXX11_RVALUE_REFS
Stack(Stack&& rhs)
: allocator_(rhs.allocator_),
ownAllocator_(rhs.ownAllocator_),
stack_(rhs.stack_),
stackTop_(rhs.stackTop_),
stackEnd_(rhs.stackEnd_),
initialCapacity_(rhs.initialCapacity_)
{
rhs.allocator_ = 0;
rhs.ownAllocator_ = 0;
rhs.stack_ = 0;
rhs.stackTop_ = 0;
rhs.stackEnd_ = 0;
rhs.initialCapacity_ = 0;
}
#endif
~Stack() {
Destroy();
}
#if RAPIDJSON_HAS_CXX11_RVALUE_REFS
Stack& operator=(Stack&& rhs) {
if (&rhs != this)
{
Destroy();
allocator_ = rhs.allocator_;
ownAllocator_ = rhs.ownAllocator_;
stack_ = rhs.stack_;
stackTop_ = rhs.stackTop_;
stackEnd_ = rhs.stackEnd_;
initialCapacity_ = rhs.initialCapacity_;
rhs.allocator_ = 0;
rhs.ownAllocator_ = 0;
rhs.stack_ = 0;
rhs.stackTop_ = 0;
rhs.stackEnd_ = 0;
rhs.initialCapacity_ = 0;
}
return *this;
}
#endif
void Clear() { stackTop_ = stack_; }
void ShrinkToFit() {
if (Empty()) {
// If the stack is empty, completely deallocate the memory.
Allocator::Free(stack_);
stack_ = 0;
stackTop_ = 0;
stackEnd_ = 0;
}
else
Resize(GetSize());
}
// Optimization note: try to minimize the size of this function for force inline.
// Expansion is run very infrequently, so it is moved to another (probably non-inline) function.
template<typename T>
RAPIDJSON_FORCEINLINE T* Push(size_t count = 1) {
// Expand the stack if needed
if (stackTop_ + sizeof(T) * count >= stackEnd_)
Expand<T>(count);
T* ret = reinterpret_cast<T*>(stackTop_);
stackTop_ += sizeof(T) * count;
return ret;
}
template<typename T>
T* Pop(size_t count) {
RAPIDJSON_ASSERT(GetSize() >= count * sizeof(T));
stackTop_ -= count * sizeof(T);
return reinterpret_cast<T*>(stackTop_);
}
template<typename T>
T* Top() {
RAPIDJSON_ASSERT(GetSize() >= sizeof(T));
return reinterpret_cast<T*>(stackTop_ - sizeof(T));
}
template<typename T>
T* Bottom() { return (T*)stack_; }
Allocator& GetAllocator() { return *allocator_; }
bool Empty() const { return stackTop_ == stack_; }
size_t GetSize() const { return static_cast<size_t>(stackTop_ - stack_); }
size_t GetCapacity() const { return static_cast<size_t>(stackEnd_ - stack_); }
private:
template<typename T>
void Expand(size_t count) {
// Only expand the capacity if the current stack exists. Otherwise just create a stack with initial capacity.
size_t newCapacity;
if (stack_ == 0) {
if (!allocator_)
ownAllocator_ = allocator_ = RAPIDJSON_NEW(Allocator());
newCapacity = initialCapacity_;
} else {
newCapacity = GetCapacity();
newCapacity += (newCapacity + 1) / 2;
}
size_t newSize = GetSize() + sizeof(T) * count;
if (newCapacity < newSize)
newCapacity = newSize;
Resize(newCapacity);
}
void Resize(size_t newCapacity) {
const size_t size = GetSize(); // Backup the current size
stack_ = (char*)allocator_->Realloc(stack_, GetCapacity(), newCapacity);
stackTop_ = stack_ + size;
stackEnd_ = stack_ + newCapacity;
}
void Destroy() {
Allocator::Free(stack_);
RAPIDJSON_DELETE(ownAllocator_); // Only delete if it is owned by the stack
}
// Prohibit copy constructor & assignment operator.
Stack(const Stack&);
Stack& operator=(const Stack&);
Allocator* allocator_;
Allocator* ownAllocator_;
char *stack_;
char *stackTop_;
char *stackEnd_;
size_t initialCapacity_;
};
} // namespace internal
RAPIDJSON_NAMESPACE_END
#endif // RAPIDJSON_STACK_H_
+37
Ver Arquivo
@@ -0,0 +1,37 @@
// Tencent is pleased to support the open source community by making RapidJSON available.
//
// Copyright (C) 2015 THL A29 Limited, a Tencent company, and Milo Yip. All rights reserved.
//
// Licensed under the MIT License (the "License"); you may not use this file except
// in compliance with the License. You may obtain a copy of the License at
//
// http://opensource.org/licenses/MIT
//
// Unless required by applicable law or agreed to in writing, software distributed
// under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
// CONDITIONS OF ANY KIND, either express or implied. See the License for the
// specific language governing permissions and limitations under the License.
#ifndef RAPIDJSON_INTERNAL_STRFUNC_H_
#define RAPIDJSON_INTERNAL_STRFUNC_H_
RAPIDJSON_NAMESPACE_BEGIN
namespace internal {
//! Custom strlen() which works on different character types.
/*! \tparam Ch Character type (e.g. char, wchar_t, short)
\param s Null-terminated input string.
\return Number of characters in the string.
\note This has the same semantics as strlen(), the return value is not number of Unicode codepoints.
*/
template <typename Ch>
inline SizeType StrLen(const Ch* s) {
const Ch* p = s;
while (*p) ++p;
return SizeType(p - s);
}
} // namespace internal
RAPIDJSON_NAMESPACE_END
#endif // RAPIDJSON_INTERNAL_STRFUNC_H_
+265
Ver Arquivo
@@ -0,0 +1,265 @@
// Tencent is pleased to support the open source community by making RapidJSON available.
//
// Copyright (C) 2015 THL A29 Limited, a Tencent company, and Milo Yip. All rights reserved.
//
// Licensed under the MIT License (the "License"); you may not use this file except
// in compliance with the License. You may obtain a copy of the License at
//
// http://opensource.org/licenses/MIT
//
// Unless required by applicable law or agreed to in writing, software distributed
// under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
// CONDITIONS OF ANY KIND, either express or implied. See the License for the
// specific language governing permissions and limitations under the License.
#ifndef RAPIDJSON_STRTOD_
#define RAPIDJSON_STRTOD_
#include "../rapidjson.h"
#include "ieee754.h"
#include "biginteger.h"
#include "diyfp.h"
#include "pow10.h"
RAPIDJSON_NAMESPACE_BEGIN
namespace internal {
inline double FastPath(double significand, int exp) {
if (exp < -308)
return 0.0;
else if (exp >= 0)
return significand * internal::Pow10(exp);
else
return significand / internal::Pow10(-exp);
}
inline double StrtodNormalPrecision(double d, int p) {
if (p < -308) {
// Prevent expSum < -308, making Pow10(p) = 0
d = FastPath(d, -308);
d = FastPath(d, p + 308);
}
else
d = FastPath(d, p);
return d;
}
template <typename T>
inline T Min3(T a, T b, T c) {
T m = a;
if (m > b) m = b;
if (m > c) m = c;
return m;
}
inline int CheckWithinHalfULP(double b, const BigInteger& d, int dExp) {
const Double db(b);
const uint64_t bInt = db.IntegerSignificand();
const int bExp = db.IntegerExponent();
const int hExp = bExp - 1;
int dS_Exp2 = 0, dS_Exp5 = 0, bS_Exp2 = 0, bS_Exp5 = 0, hS_Exp2 = 0, hS_Exp5 = 0;
// Adjust for decimal exponent
if (dExp >= 0) {
dS_Exp2 += dExp;
dS_Exp5 += dExp;
}
else {
bS_Exp2 -= dExp;
bS_Exp5 -= dExp;
hS_Exp2 -= dExp;
hS_Exp5 -= dExp;
}
// Adjust for binary exponent
if (bExp >= 0)
bS_Exp2 += bExp;
else {
dS_Exp2 -= bExp;
hS_Exp2 -= bExp;
}
// Adjust for half ulp exponent
if (hExp >= 0)
hS_Exp2 += hExp;
else {
dS_Exp2 -= hExp;
bS_Exp2 -= hExp;
}
// Remove common power of two factor from all three scaled values
int common_Exp2 = Min3(dS_Exp2, bS_Exp2, hS_Exp2);
dS_Exp2 -= common_Exp2;
bS_Exp2 -= common_Exp2;
hS_Exp2 -= common_Exp2;
BigInteger dS = d;
dS.MultiplyPow5(dS_Exp5) <<= dS_Exp2;
BigInteger bS(bInt);
bS.MultiplyPow5(bS_Exp5) <<= bS_Exp2;
BigInteger hS(1);
hS.MultiplyPow5(hS_Exp5) <<= hS_Exp2;
BigInteger delta(0);
dS.Difference(bS, &delta);
return delta.Compare(hS);
}
inline bool StrtodFast(double d, int p, double* result) {
// Use fast path for string-to-double conversion if possible
// see http://www.exploringbinary.com/fast-path-decimal-to-floating-point-conversion/
if (p > 22 && p < 22 + 16) {
// Fast Path Cases In Disguise
d *= internal::Pow10(p - 22);
p = 22;
}
if (p >= -22 && p <= 22 && d <= 9007199254740991.0) { // 2^53 - 1
*result = FastPath(d, p);
return true;
}
else
return false;
}
// Compute an approximation and see if it is within 1/2 ULP
inline bool StrtodDiyFp(const char* decimals, size_t length, size_t decimalPosition, int exp, double* result) {
uint64_t significand = 0;
size_t i = 0; // 2^64 - 1 = 18446744073709551615, 1844674407370955161 = 0x1999999999999999
for (; i < length; i++) {
if (significand > RAPIDJSON_UINT64_C2(0x19999999, 0x99999999) ||
(significand == RAPIDJSON_UINT64_C2(0x19999999, 0x99999999) && decimals[i] > '5'))
break;
significand = significand * 10 + (decimals[i] - '0');
}
if (i < length && decimals[i] >= '5') // Rounding
significand++;
size_t remaining = length - i;
const unsigned kUlpShift = 3;
const unsigned kUlp = 1 << kUlpShift;
int error = (remaining == 0) ? 0 : kUlp / 2;
DiyFp v(significand, 0);
v = v.Normalize();
error <<= -v.e;
const int dExp = (int)decimalPosition - (int)i + exp;
int actualExp;
DiyFp cachedPower = GetCachedPower10(dExp, &actualExp);
if (actualExp != dExp) {
static const DiyFp kPow10[] = {
DiyFp(RAPIDJSON_UINT64_C2(0xa0000000, 00000000), -60), // 10^1
DiyFp(RAPIDJSON_UINT64_C2(0xc8000000, 00000000), -57), // 10^2
DiyFp(RAPIDJSON_UINT64_C2(0xfa000000, 00000000), -54), // 10^3
DiyFp(RAPIDJSON_UINT64_C2(0x9c400000, 00000000), -50), // 10^4
DiyFp(RAPIDJSON_UINT64_C2(0xc3500000, 00000000), -47), // 10^5
DiyFp(RAPIDJSON_UINT64_C2(0xf4240000, 00000000), -44), // 10^6
DiyFp(RAPIDJSON_UINT64_C2(0x98968000, 00000000), -40) // 10^7
};
int adjustment = dExp - actualExp - 1;
RAPIDJSON_ASSERT(adjustment >= 0 && adjustment < 7);
v = v * kPow10[adjustment];
if (length + adjustment > 19) // has more digits than decimal digits in 64-bit
error += kUlp / 2;
}
v = v * cachedPower;
error += kUlp + (error == 0 ? 0 : 1);
const int oldExp = v.e;
v = v.Normalize();
error <<= oldExp - v.e;
const unsigned effectiveSignificandSize = Double::EffectiveSignificandSize(64 + v.e);
unsigned precisionSize = 64 - effectiveSignificandSize;
if (precisionSize + kUlpShift >= 64) {
unsigned scaleExp = (precisionSize + kUlpShift) - 63;
v.f >>= scaleExp;
v.e += scaleExp;
error = (error >> scaleExp) + 1 + kUlp;
precisionSize -= scaleExp;
}
DiyFp rounded(v.f >> precisionSize, v.e + precisionSize);
const uint64_t precisionBits = (v.f & ((uint64_t(1) << precisionSize) - 1)) * kUlp;
const uint64_t halfWay = (uint64_t(1) << (precisionSize - 1)) * kUlp;
if (precisionBits >= halfWay + error)
rounded.f++;
*result = rounded.ToDouble();
return halfWay - error >= precisionBits || precisionBits >= halfWay + error;
}
inline double StrtodBigInteger(double approx, const char* decimals, size_t length, size_t decimalPosition, int exp) {
const BigInteger dInt(decimals, length);
const int dExp = (int)decimalPosition - (int)length + exp;
Double a(approx);
int cmp = CheckWithinHalfULP(a.Value(), dInt, dExp);
if (cmp < 0)
return a.Value(); // within half ULP
else if (cmp == 0) {
// Round towards even
if (a.Significand() & 1)
return a.NextPositiveDouble();
else
return a.Value();
}
else // adjustment
return a.NextPositiveDouble();
}
inline double StrtodFullPrecision(double d, int p, const char* decimals, size_t length, size_t decimalPosition, int exp) {
RAPIDJSON_ASSERT(d >= 0.0);
RAPIDJSON_ASSERT(length >= 1);
double result;
if (StrtodFast(d, p, &result))
return result;
// Trim leading zeros
while (*decimals == '0' && length > 1) {
length--;
decimals++;
decimalPosition--;
}
// Trim trailing zeros
while (decimals[length - 1] == '0' && length > 1) {
length--;
decimalPosition--;
exp++;
}
// Trim right-most digits
const int kMaxDecimalDigit = 780;
if ((int)length > kMaxDecimalDigit) {
int delta = (int(length) - kMaxDecimalDigit);
exp += delta;
decimalPosition -= delta;
length = kMaxDecimalDigit;
}
// If too small, underflow to zero
if (int(length) + exp < -324)
return 0.0;
if (StrtodDiyFp(decimals, length, decimalPosition, exp, &result))
return result;
// Use approximation from StrtodDiyFp and make adjustment with BigInteger comparison
return StrtodBigInteger(result, decimals, length, decimalPosition, exp);
}
} // namespace internal
RAPIDJSON_NAMESPACE_END
#endif // RAPIDJSON_STRTOD_
+57
Ver Arquivo
@@ -0,0 +1,57 @@
Tencent is pleased to support the open source community by making RapidJSON available.
Copyright (C) 2015 THL A29 Limited, a Tencent company, and Milo Yip. All rights reserved.
If you have downloaded a copy of the RapidJSON binary from Tencent, please note that the RapidJSON binary is licensed under the MIT License.
If you have downloaded a copy of the RapidJSON source code from Tencent, please note that RapidJSON source code is licensed under the MIT License, except for the third-party components listed below which are subject to different license terms. Your integration of RapidJSON into your own projects may require compliance with the MIT License, as well as the other licenses applicable to the third-party components included within RapidJSON.
A copy of the MIT License is included in this file.
Other dependencies and licenses:
Open Source Software Licensed Under the BSD License:
--------------------------------------------------------------------
The msinttypes r29
Copyright (c) 2006-2013 Alexander Chemeris
All rights reserved.
Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
* Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.
* Neither the name of copyright holder nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS AND CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
Open Source Software Licensed Under the JSON License:
--------------------------------------------------------------------
json.org
Copyright (c) 2002 JSON.org
All Rights Reserved.
JSON_checker
Copyright (c) 2002 JSON.org
All Rights Reserved.
Terms of the JSON License:
---------------------------------------------------
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
The Software shall be used for Good, not Evil.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
Terms of the MIT License:
--------------------------------------------------------------------
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+70
Ver Arquivo
@@ -0,0 +1,70 @@
// Tencent is pleased to support the open source community by making RapidJSON available.
//
// Copyright (C) 2015 THL A29 Limited, a Tencent company, and Milo Yip. All rights reserved.
//
// Licensed under the MIT License (the "License"); you may not use this file except
// in compliance with the License. You may obtain a copy of the License at
//
// http://opensource.org/licenses/MIT
//
// Unless required by applicable law or agreed to in writing, software distributed
// under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
// CONDITIONS OF ANY KIND, either express or implied. See the License for the
// specific language governing permissions and limitations under the License.
#ifndef RAPIDJSON_MEMORYBUFFER_H_
#define RAPIDJSON_MEMORYBUFFER_H_
#include "rapidjson.h"
#include "internal/stack.h"
RAPIDJSON_NAMESPACE_BEGIN
//! Represents an in-memory output byte stream.
/*!
This class is mainly for being wrapped by EncodedOutputStream or AutoUTFOutputStream.
It is similar to FileWriteBuffer but the destination is an in-memory buffer instead of a file.
Differences between MemoryBuffer and StringBuffer:
1. StringBuffer has Encoding but MemoryBuffer is only a byte buffer.
2. StringBuffer::GetString() returns a null-terminated string. MemoryBuffer::GetBuffer() returns a buffer without terminator.
\tparam Allocator type for allocating memory buffer.
\note implements Stream concept
*/
template <typename Allocator = CrtAllocator>
struct GenericMemoryBuffer {
typedef char Ch; // byte
GenericMemoryBuffer(Allocator* allocator = 0, size_t capacity = kDefaultCapacity) : stack_(allocator, capacity) {}
void Put(Ch c) { *stack_.template Push<Ch>() = c; }
void Flush() {}
void Clear() { stack_.Clear(); }
void ShrinkToFit() { stack_.ShrinkToFit(); }
Ch* Push(size_t count) { return stack_.template Push<Ch>(count); }
void Pop(size_t count) { stack_.template Pop<Ch>(count); }
const Ch* GetBuffer() const {
return stack_.template Bottom<Ch>();
}
size_t GetSize() const { return stack_.GetSize(); }
static const size_t kDefaultCapacity = 256;
mutable internal::Stack<Allocator> stack_;
};
typedef GenericMemoryBuffer<> MemoryBuffer;
//! Implement specialized version of PutN() with memset() for better performance.
template<>
inline void PutN(MemoryBuffer& memoryBuffer, char c, size_t n) {
std::memset(memoryBuffer.stack_.Push<char>(n), c, n * sizeof(c));
}
RAPIDJSON_NAMESPACE_END
#endif // RAPIDJSON_MEMORYBUFFER_H_
+61
Ver Arquivo
@@ -0,0 +1,61 @@
// Tencent is pleased to support the open source community by making RapidJSON available.
//
// Copyright (C) 2015 THL A29 Limited, a Tencent company, and Milo Yip. All rights reserved.
//
// Licensed under the MIT License (the "License"); you may not use this file except
// in compliance with the License. You may obtain a copy of the License at
//
// http://opensource.org/licenses/MIT
//
// Unless required by applicable law or agreed to in writing, software distributed
// under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
// CONDITIONS OF ANY KIND, either express or implied. See the License for the
// specific language governing permissions and limitations under the License.
#ifndef RAPIDJSON_MEMORYSTREAM_H_
#define RAPIDJSON_MEMORYSTREAM_H_
#include "rapidjson.h"
RAPIDJSON_NAMESPACE_BEGIN
//! Represents an in-memory input byte stream.
/*!
This class is mainly for being wrapped by EncodedInputStream or AutoUTFInputStream.
It is similar to FileReadBuffer but the source is an in-memory buffer instead of a file.
Differences between MemoryStream and StringStream:
1. StringStream has encoding but MemoryStream is a byte stream.
2. MemoryStream needs size of the source buffer and the buffer don't need to be null terminated. StringStream assume null-terminated string as source.
3. MemoryStream supports Peek4() for encoding detection. StringStream is specified with an encoding so it should not have Peek4().
\note implements Stream concept
*/
struct MemoryStream {
typedef char Ch; // byte
MemoryStream(const Ch *src, size_t size) : src_(src), begin_(src), end_(src + size), size_(size) {}
Ch Peek() const { return (src_ == end_) ? '\0' : *src_; }
Ch Take() { return (src_ == end_) ? '\0' : *src_++; }
size_t Tell() const { return static_cast<size_t>(src_ - begin_); }
Ch* PutBegin() { RAPIDJSON_ASSERT(false); return 0; }
void Put(Ch) { RAPIDJSON_ASSERT(false); }
void Flush() { RAPIDJSON_ASSERT(false); }
size_t PutEnd(Ch*) { RAPIDJSON_ASSERT(false); return 0; }
// For encoding detection only.
const Ch* Peek4() const {
return Tell() + 4 <= size_ ? src_ : 0;
}
const Ch* src_; //!< Current read position.
const Ch* begin_; //!< Original head of the string.
const Ch* end_; //!< End of stream.
size_t size_; //!< Size of the stream.
};
RAPIDJSON_NAMESPACE_END
#endif // RAPIDJSON_MEMORYBUFFER_H_
+316
Ver Arquivo
@@ -0,0 +1,316 @@
// ISO C9x compliant inttypes.h for Microsoft Visual Studio
// Based on ISO/IEC 9899:TC2 Committee draft (May 6, 2005) WG14/N1124
//
// Copyright (c) 2006-2013 Alexander Chemeris
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are met:
//
// 1. Redistributions of source code must retain the above copyright notice,
// this list of conditions and the following disclaimer.
//
// 2. Redistributions in binary form must reproduce the above copyright
// notice, this list of conditions and the following disclaimer in the
// documentation and/or other materials provided with the distribution.
//
// 3. Neither the name of the product nor the names of its contributors may
// be used to endorse or promote products derived from this software
// without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
// WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
// MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
// EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
// OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
// WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
// OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
// ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
//
///////////////////////////////////////////////////////////////////////////////
// The above software in this distribution may have been modified by
// THL A29 Limited ("Tencent Modifications").
// All Tencent Modifications are Copyright (C) 2015 THL A29 Limited.
#ifndef _MSC_VER // [
#error "Use this header only with Microsoft Visual C++ compilers!"
#endif // _MSC_VER ]
#ifndef _MSC_INTTYPES_H_ // [
#define _MSC_INTTYPES_H_
#if _MSC_VER > 1000
#pragma once
#endif
#include "stdint.h"
// miloyip: VC supports inttypes.h since VC2013
#if _MSC_VER >= 1800
#include <inttypes.h>
#else
// 7.8 Format conversion of integer types
typedef struct {
intmax_t quot;
intmax_t rem;
} imaxdiv_t;
// 7.8.1 Macros for format specifiers
#if !defined(__cplusplus) || defined(__STDC_FORMAT_MACROS) // [ See footnote 185 at page 198
// The fprintf macros for signed integers are:
#define PRId8 "d"
#define PRIi8 "i"
#define PRIdLEAST8 "d"
#define PRIiLEAST8 "i"
#define PRIdFAST8 "d"
#define PRIiFAST8 "i"
#define PRId16 "hd"
#define PRIi16 "hi"
#define PRIdLEAST16 "hd"
#define PRIiLEAST16 "hi"
#define PRIdFAST16 "hd"
#define PRIiFAST16 "hi"
#define PRId32 "I32d"
#define PRIi32 "I32i"
#define PRIdLEAST32 "I32d"
#define PRIiLEAST32 "I32i"
#define PRIdFAST32 "I32d"
#define PRIiFAST32 "I32i"
#define PRId64 "I64d"
#define PRIi64 "I64i"
#define PRIdLEAST64 "I64d"
#define PRIiLEAST64 "I64i"
#define PRIdFAST64 "I64d"
#define PRIiFAST64 "I64i"
#define PRIdMAX "I64d"
#define PRIiMAX "I64i"
#define PRIdPTR "Id"
#define PRIiPTR "Ii"
// The fprintf macros for unsigned integers are:
#define PRIo8 "o"
#define PRIu8 "u"
#define PRIx8 "x"
#define PRIX8 "X"
#define PRIoLEAST8 "o"
#define PRIuLEAST8 "u"
#define PRIxLEAST8 "x"
#define PRIXLEAST8 "X"
#define PRIoFAST8 "o"
#define PRIuFAST8 "u"
#define PRIxFAST8 "x"
#define PRIXFAST8 "X"
#define PRIo16 "ho"
#define PRIu16 "hu"
#define PRIx16 "hx"
#define PRIX16 "hX"
#define PRIoLEAST16 "ho"
#define PRIuLEAST16 "hu"
#define PRIxLEAST16 "hx"
#define PRIXLEAST16 "hX"
#define PRIoFAST16 "ho"
#define PRIuFAST16 "hu"
#define PRIxFAST16 "hx"
#define PRIXFAST16 "hX"
#define PRIo32 "I32o"
#define PRIu32 "I32u"
#define PRIx32 "I32x"
#define PRIX32 "I32X"
#define PRIoLEAST32 "I32o"
#define PRIuLEAST32 "I32u"
#define PRIxLEAST32 "I32x"
#define PRIXLEAST32 "I32X"
#define PRIoFAST32 "I32o"
#define PRIuFAST32 "I32u"
#define PRIxFAST32 "I32x"
#define PRIXFAST32 "I32X"
#define PRIo64 "I64o"
#define PRIu64 "I64u"
#define PRIx64 "I64x"
#define PRIX64 "I64X"
#define PRIoLEAST64 "I64o"
#define PRIuLEAST64 "I64u"
#define PRIxLEAST64 "I64x"
#define PRIXLEAST64 "I64X"
#define PRIoFAST64 "I64o"
#define PRIuFAST64 "I64u"
#define PRIxFAST64 "I64x"
#define PRIXFAST64 "I64X"
#define PRIoMAX "I64o"
#define PRIuMAX "I64u"
#define PRIxMAX "I64x"
#define PRIXMAX "I64X"
#define PRIoPTR "Io"
#define PRIuPTR "Iu"
#define PRIxPTR "Ix"
#define PRIXPTR "IX"
// The fscanf macros for signed integers are:
#define SCNd8 "d"
#define SCNi8 "i"
#define SCNdLEAST8 "d"
#define SCNiLEAST8 "i"
#define SCNdFAST8 "d"
#define SCNiFAST8 "i"
#define SCNd16 "hd"
#define SCNi16 "hi"
#define SCNdLEAST16 "hd"
#define SCNiLEAST16 "hi"
#define SCNdFAST16 "hd"
#define SCNiFAST16 "hi"
#define SCNd32 "ld"
#define SCNi32 "li"
#define SCNdLEAST32 "ld"
#define SCNiLEAST32 "li"
#define SCNdFAST32 "ld"
#define SCNiFAST32 "li"
#define SCNd64 "I64d"
#define SCNi64 "I64i"
#define SCNdLEAST64 "I64d"
#define SCNiLEAST64 "I64i"
#define SCNdFAST64 "I64d"
#define SCNiFAST64 "I64i"
#define SCNdMAX "I64d"
#define SCNiMAX "I64i"
#ifdef _WIN64 // [
# define SCNdPTR "I64d"
# define SCNiPTR "I64i"
#else // _WIN64 ][
# define SCNdPTR "ld"
# define SCNiPTR "li"
#endif // _WIN64 ]
// The fscanf macros for unsigned integers are:
#define SCNo8 "o"
#define SCNu8 "u"
#define SCNx8 "x"
#define SCNX8 "X"
#define SCNoLEAST8 "o"
#define SCNuLEAST8 "u"
#define SCNxLEAST8 "x"
#define SCNXLEAST8 "X"
#define SCNoFAST8 "o"
#define SCNuFAST8 "u"
#define SCNxFAST8 "x"
#define SCNXFAST8 "X"
#define SCNo16 "ho"
#define SCNu16 "hu"
#define SCNx16 "hx"
#define SCNX16 "hX"
#define SCNoLEAST16 "ho"
#define SCNuLEAST16 "hu"
#define SCNxLEAST16 "hx"
#define SCNXLEAST16 "hX"
#define SCNoFAST16 "ho"
#define SCNuFAST16 "hu"
#define SCNxFAST16 "hx"
#define SCNXFAST16 "hX"
#define SCNo32 "lo"
#define SCNu32 "lu"
#define SCNx32 "lx"
#define SCNX32 "lX"
#define SCNoLEAST32 "lo"
#define SCNuLEAST32 "lu"
#define SCNxLEAST32 "lx"
#define SCNXLEAST32 "lX"
#define SCNoFAST32 "lo"
#define SCNuFAST32 "lu"
#define SCNxFAST32 "lx"
#define SCNXFAST32 "lX"
#define SCNo64 "I64o"
#define SCNu64 "I64u"
#define SCNx64 "I64x"
#define SCNX64 "I64X"
#define SCNoLEAST64 "I64o"
#define SCNuLEAST64 "I64u"
#define SCNxLEAST64 "I64x"
#define SCNXLEAST64 "I64X"
#define SCNoFAST64 "I64o"
#define SCNuFAST64 "I64u"
#define SCNxFAST64 "I64x"
#define SCNXFAST64 "I64X"
#define SCNoMAX "I64o"
#define SCNuMAX "I64u"
#define SCNxMAX "I64x"
#define SCNXMAX "I64X"
#ifdef _WIN64 // [
# define SCNoPTR "I64o"
# define SCNuPTR "I64u"
# define SCNxPTR "I64x"
# define SCNXPTR "I64X"
#else // _WIN64 ][
# define SCNoPTR "lo"
# define SCNuPTR "lu"
# define SCNxPTR "lx"
# define SCNXPTR "lX"
#endif // _WIN64 ]
#endif // __STDC_FORMAT_MACROS ]
// 7.8.2 Functions for greatest-width integer types
// 7.8.2.1 The imaxabs function
#define imaxabs _abs64
// 7.8.2.2 The imaxdiv function
// This is modified version of div() function from Microsoft's div.c found
// in %MSVC.NET%\crt\src\div.c
#ifdef STATIC_IMAXDIV // [
static
#else // STATIC_IMAXDIV ][
_inline
#endif // STATIC_IMAXDIV ]
imaxdiv_t __cdecl imaxdiv(intmax_t numer, intmax_t denom)
{
imaxdiv_t result;
result.quot = numer / denom;
result.rem = numer % denom;
if (numer < 0 && result.rem > 0) {
// did division wrong; must fix up
++result.quot;
result.rem -= denom;
}
return result;
}
// 7.8.2.3 The strtoimax and strtoumax functions
#define strtoimax _strtoi64
#define strtoumax _strtoui64
// 7.8.2.4 The wcstoimax and wcstoumax functions
#define wcstoimax _wcstoi64
#define wcstoumax _wcstoui64
#endif // _MSC_VER >= 1800
#endif // _MSC_INTTYPES_H_ ]
+300
Ver Arquivo
@@ -0,0 +1,300 @@
// ISO C9x compliant stdint.h for Microsoft Visual Studio
// Based on ISO/IEC 9899:TC2 Committee draft (May 6, 2005) WG14/N1124
//
// Copyright (c) 2006-2013 Alexander Chemeris
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are met:
//
// 1. Redistributions of source code must retain the above copyright notice,
// this list of conditions and the following disclaimer.
//
// 2. Redistributions in binary form must reproduce the above copyright
// notice, this list of conditions and the following disclaimer in the
// documentation and/or other materials provided with the distribution.
//
// 3. Neither the name of the product nor the names of its contributors may
// be used to endorse or promote products derived from this software
// without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
// WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
// MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
// EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
// OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
// WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
// OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
// ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
//
///////////////////////////////////////////////////////////////////////////////
// The above software in this distribution may have been modified by
// THL A29 Limited ("Tencent Modifications").
// All Tencent Modifications are Copyright (C) 2015 THL A29 Limited.
#ifndef _MSC_VER // [
#error "Use this header only with Microsoft Visual C++ compilers!"
#endif // _MSC_VER ]
#ifndef _MSC_STDINT_H_ // [
#define _MSC_STDINT_H_
#if _MSC_VER > 1000
#pragma once
#endif
// miloyip: Originally Visual Studio 2010 uses its own stdint.h. However it generates warning with INT64_C(), so change to use this file for vs2010.
#if _MSC_VER >= 1600 // [
#include <stdint.h>
#if !defined(__cplusplus) || defined(__STDC_CONSTANT_MACROS) // [ See footnote 224 at page 260
#undef INT8_C
#undef INT16_C
#undef INT32_C
#undef INT64_C
#undef UINT8_C
#undef UINT16_C
#undef UINT32_C
#undef UINT64_C
// 7.18.4.1 Macros for minimum-width integer constants
#define INT8_C(val) val##i8
#define INT16_C(val) val##i16
#define INT32_C(val) val##i32
#define INT64_C(val) val##i64
#define UINT8_C(val) val##ui8
#define UINT16_C(val) val##ui16
#define UINT32_C(val) val##ui32
#define UINT64_C(val) val##ui64
// 7.18.4.2 Macros for greatest-width integer constants
// These #ifndef's are needed to prevent collisions with <boost/cstdint.hpp>.
// Check out Issue 9 for the details.
#ifndef INTMAX_C // [
# define INTMAX_C INT64_C
#endif // INTMAX_C ]
#ifndef UINTMAX_C // [
# define UINTMAX_C UINT64_C
#endif // UINTMAX_C ]
#endif // __STDC_CONSTANT_MACROS ]
#else // ] _MSC_VER >= 1700 [
#include <limits.h>
// For Visual Studio 6 in C++ mode and for many Visual Studio versions when
// compiling for ARM we should wrap <wchar.h> include with 'extern "C++" {}'
// or compiler give many errors like this:
// error C2733: second C linkage of overloaded function 'wmemchr' not allowed
#ifdef __cplusplus
extern "C" {
#endif
# include <wchar.h>
#ifdef __cplusplus
}
#endif
// Define _W64 macros to mark types changing their size, like intptr_t.
#ifndef _W64
# if !defined(__midl) && (defined(_X86_) || defined(_M_IX86)) && _MSC_VER >= 1300
# define _W64 __w64
# else
# define _W64
# endif
#endif
// 7.18.1 Integer types
// 7.18.1.1 Exact-width integer types
// Visual Studio 6 and Embedded Visual C++ 4 doesn't
// realize that, e.g. char has the same size as __int8
// so we give up on __intX for them.
#if (_MSC_VER < 1300)
typedef signed char int8_t;
typedef signed short int16_t;
typedef signed int int32_t;
typedef unsigned char uint8_t;
typedef unsigned short uint16_t;
typedef unsigned int uint32_t;
#else
typedef signed __int8 int8_t;
typedef signed __int16 int16_t;
typedef signed __int32 int32_t;
typedef unsigned __int8 uint8_t;
typedef unsigned __int16 uint16_t;
typedef unsigned __int32 uint32_t;
#endif
typedef signed __int64 int64_t;
typedef unsigned __int64 uint64_t;
// 7.18.1.2 Minimum-width integer types
typedef int8_t int_least8_t;
typedef int16_t int_least16_t;
typedef int32_t int_least32_t;
typedef int64_t int_least64_t;
typedef uint8_t uint_least8_t;
typedef uint16_t uint_least16_t;
typedef uint32_t uint_least32_t;
typedef uint64_t uint_least64_t;
// 7.18.1.3 Fastest minimum-width integer types
typedef int8_t int_fast8_t;
typedef int16_t int_fast16_t;
typedef int32_t int_fast32_t;
typedef int64_t int_fast64_t;
typedef uint8_t uint_fast8_t;
typedef uint16_t uint_fast16_t;
typedef uint32_t uint_fast32_t;
typedef uint64_t uint_fast64_t;
// 7.18.1.4 Integer types capable of holding object pointers
#ifdef _WIN64 // [
typedef signed __int64 intptr_t;
typedef unsigned __int64 uintptr_t;
#else // _WIN64 ][
typedef _W64 signed int intptr_t;
typedef _W64 unsigned int uintptr_t;
#endif // _WIN64 ]
// 7.18.1.5 Greatest-width integer types
typedef int64_t intmax_t;
typedef uint64_t uintmax_t;
// 7.18.2 Limits of specified-width integer types
#if !defined(__cplusplus) || defined(__STDC_LIMIT_MACROS) // [ See footnote 220 at page 257 and footnote 221 at page 259
// 7.18.2.1 Limits of exact-width integer types
#define INT8_MIN ((int8_t)_I8_MIN)
#define INT8_MAX _I8_MAX
#define INT16_MIN ((int16_t)_I16_MIN)
#define INT16_MAX _I16_MAX
#define INT32_MIN ((int32_t)_I32_MIN)
#define INT32_MAX _I32_MAX
#define INT64_MIN ((int64_t)_I64_MIN)
#define INT64_MAX _I64_MAX
#define UINT8_MAX _UI8_MAX
#define UINT16_MAX _UI16_MAX
#define UINT32_MAX _UI32_MAX
#define UINT64_MAX _UI64_MAX
// 7.18.2.2 Limits of minimum-width integer types
#define INT_LEAST8_MIN INT8_MIN
#define INT_LEAST8_MAX INT8_MAX
#define INT_LEAST16_MIN INT16_MIN
#define INT_LEAST16_MAX INT16_MAX
#define INT_LEAST32_MIN INT32_MIN
#define INT_LEAST32_MAX INT32_MAX
#define INT_LEAST64_MIN INT64_MIN
#define INT_LEAST64_MAX INT64_MAX
#define UINT_LEAST8_MAX UINT8_MAX
#define UINT_LEAST16_MAX UINT16_MAX
#define UINT_LEAST32_MAX UINT32_MAX
#define UINT_LEAST64_MAX UINT64_MAX
// 7.18.2.3 Limits of fastest minimum-width integer types
#define INT_FAST8_MIN INT8_MIN
#define INT_FAST8_MAX INT8_MAX
#define INT_FAST16_MIN INT16_MIN
#define INT_FAST16_MAX INT16_MAX
#define INT_FAST32_MIN INT32_MIN
#define INT_FAST32_MAX INT32_MAX
#define INT_FAST64_MIN INT64_MIN
#define INT_FAST64_MAX INT64_MAX
#define UINT_FAST8_MAX UINT8_MAX
#define UINT_FAST16_MAX UINT16_MAX
#define UINT_FAST32_MAX UINT32_MAX
#define UINT_FAST64_MAX UINT64_MAX
// 7.18.2.4 Limits of integer types capable of holding object pointers
#ifdef _WIN64 // [
# define INTPTR_MIN INT64_MIN
# define INTPTR_MAX INT64_MAX
# define UINTPTR_MAX UINT64_MAX
#else // _WIN64 ][
# define INTPTR_MIN INT32_MIN
# define INTPTR_MAX INT32_MAX
# define UINTPTR_MAX UINT32_MAX
#endif // _WIN64 ]
// 7.18.2.5 Limits of greatest-width integer types
#define INTMAX_MIN INT64_MIN
#define INTMAX_MAX INT64_MAX
#define UINTMAX_MAX UINT64_MAX
// 7.18.3 Limits of other integer types
#ifdef _WIN64 // [
# define PTRDIFF_MIN _I64_MIN
# define PTRDIFF_MAX _I64_MAX
#else // _WIN64 ][
# define PTRDIFF_MIN _I32_MIN
# define PTRDIFF_MAX _I32_MAX
#endif // _WIN64 ]
#define SIG_ATOMIC_MIN INT_MIN
#define SIG_ATOMIC_MAX INT_MAX
#ifndef SIZE_MAX // [
# ifdef _WIN64 // [
# define SIZE_MAX _UI64_MAX
# else // _WIN64 ][
# define SIZE_MAX _UI32_MAX
# endif // _WIN64 ]
#endif // SIZE_MAX ]
// WCHAR_MIN and WCHAR_MAX are also defined in <wchar.h>
#ifndef WCHAR_MIN // [
# define WCHAR_MIN 0
#endif // WCHAR_MIN ]
#ifndef WCHAR_MAX // [
# define WCHAR_MAX _UI16_MAX
#endif // WCHAR_MAX ]
#define WINT_MIN 0
#define WINT_MAX _UI16_MAX
#endif // __STDC_LIMIT_MACROS ]
// 7.18.4 Limits of other integer types
#if !defined(__cplusplus) || defined(__STDC_CONSTANT_MACROS) // [ See footnote 224 at page 260
// 7.18.4.1 Macros for minimum-width integer constants
#define INT8_C(val) val##i8
#define INT16_C(val) val##i16
#define INT32_C(val) val##i32
#define INT64_C(val) val##i64
#define UINT8_C(val) val##ui8
#define UINT16_C(val) val##ui16
#define UINT32_C(val) val##ui32
#define UINT64_C(val) val##ui64
// 7.18.4.2 Macros for greatest-width integer constants
// These #ifndef's are needed to prevent collisions with <boost/cstdint.hpp>.
// Check out Issue 9 for the details.
#ifndef INTMAX_C // [
# define INTMAX_C INT64_C
#endif // INTMAX_C ]
#ifndef UINTMAX_C // [
# define UINTMAX_C UINT64_C
#endif // UINTMAX_C ]
#endif // __STDC_CONSTANT_MACROS ]
#endif // _MSC_VER >= 1600 ]
#endif // _MSC_STDINT_H_ ]
+207
Ver Arquivo
@@ -0,0 +1,207 @@
// Tencent is pleased to support the open source community by making RapidJSON available.
//
// Copyright (C) 2015 THL A29 Limited, a Tencent company, and Milo Yip. All rights reserved.
//
// Licensed under the MIT License (the "License"); you may not use this file except
// in compliance with the License. You may obtain a copy of the License at
//
// http://opensource.org/licenses/MIT
//
// Unless required by applicable law or agreed to in writing, software distributed
// under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
// CONDITIONS OF ANY KIND, either express or implied. See the License for the
// specific language governing permissions and limitations under the License.
#ifndef RAPIDJSON_PRETTYWRITER_H_
#define RAPIDJSON_PRETTYWRITER_H_
#include "writer.h"
#ifdef __GNUC__
RAPIDJSON_DIAG_PUSH
RAPIDJSON_DIAG_OFF(effc++)
#endif
RAPIDJSON_NAMESPACE_BEGIN
//! Writer with indentation and spacing.
/*!
\tparam OutputStream Type of ouptut os.
\tparam SourceEncoding Encoding of source string.
\tparam TargetEncoding Encoding of output stream.
\tparam StackAllocator Type of allocator for allocating memory of stack.
*/
template<typename OutputStream, typename SourceEncoding = UTF8<>, typename TargetEncoding = UTF8<>, typename StackAllocator = CrtAllocator>
class PrettyWriter : public Writer<OutputStream, SourceEncoding, TargetEncoding, StackAllocator> {
public:
typedef Writer<OutputStream, SourceEncoding, TargetEncoding, StackAllocator> Base;
typedef typename Base::Ch Ch;
//! Constructor
/*! \param os Output stream.
\param allocator User supplied allocator. If it is null, it will create a private one.
\param levelDepth Initial capacity of stack.
*/
PrettyWriter(OutputStream& os, StackAllocator* allocator = 0, size_t levelDepth = Base::kDefaultLevelDepth) :
Base(os, allocator, levelDepth), indentChar_(' '), indentCharCount_(4) {}
//! Set custom indentation.
/*! \param indentChar Character for indentation. Must be whitespace character (' ', '\\t', '\\n', '\\r').
\param indentCharCount Number of indent characters for each indentation level.
\note The default indentation is 4 spaces.
*/
PrettyWriter& SetIndent(Ch indentChar, unsigned indentCharCount) {
RAPIDJSON_ASSERT(indentChar == ' ' || indentChar == '\t' || indentChar == '\n' || indentChar == '\r');
indentChar_ = indentChar;
indentCharCount_ = indentCharCount;
return *this;
}
/*! @name Implementation of Handler
\see Handler
*/
//@{
bool Null() { PrettyPrefix(kNullType); return Base::WriteNull(); }
bool Bool(bool b) { PrettyPrefix(b ? kTrueType : kFalseType); return Base::WriteBool(b); }
bool Int(int i) { PrettyPrefix(kNumberType); return Base::WriteInt(i); }
bool Uint(unsigned u) { PrettyPrefix(kNumberType); return Base::WriteUint(u); }
bool Int64(int64_t i64) { PrettyPrefix(kNumberType); return Base::WriteInt64(i64); }
bool Uint64(uint64_t u64) { PrettyPrefix(kNumberType); return Base::WriteUint64(u64); }
bool Double(double d) { PrettyPrefix(kNumberType); return Base::WriteDouble(d); }
bool String(const Ch* str, SizeType length, bool copy = false) {
(void)copy;
PrettyPrefix(kStringType);
return Base::WriteString(str, length);
}
#if RAPIDJSON_HAS_STDSTRING
bool String(const std::basic_string<Ch>& str) {
return String(str.data(), SizeType(str.size()));
}
#endif
bool StartObject() {
PrettyPrefix(kObjectType);
new (Base::level_stack_.template Push<typename Base::Level>()) typename Base::Level(false);
return Base::WriteStartObject();
}
bool Key(const Ch* str, SizeType length, bool copy = false) { return String(str, length, copy); }
bool EndObject(SizeType memberCount = 0) {
(void)memberCount;
RAPIDJSON_ASSERT(Base::level_stack_.GetSize() >= sizeof(typename Base::Level));
RAPIDJSON_ASSERT(!Base::level_stack_.template Top<typename Base::Level>()->inArray);
bool empty = Base::level_stack_.template Pop<typename Base::Level>(1)->valueCount == 0;
if (!empty) {
Base::os_->Put('\n');
WriteIndent();
}
bool ret = Base::WriteEndObject();
(void)ret;
RAPIDJSON_ASSERT(ret == true);
if (Base::level_stack_.Empty()) // end of json text
Base::os_->Flush();
return true;
}
bool StartArray() {
PrettyPrefix(kArrayType);
new (Base::level_stack_.template Push<typename Base::Level>()) typename Base::Level(true);
return Base::WriteStartArray();
}
bool EndArray(SizeType memberCount = 0) {
(void)memberCount;
RAPIDJSON_ASSERT(Base::level_stack_.GetSize() >= sizeof(typename Base::Level));
RAPIDJSON_ASSERT(Base::level_stack_.template Top<typename Base::Level>()->inArray);
bool empty = Base::level_stack_.template Pop<typename Base::Level>(1)->valueCount == 0;
if (!empty) {
Base::os_->Put('\n');
WriteIndent();
}
bool ret = Base::WriteEndArray();
(void)ret;
RAPIDJSON_ASSERT(ret == true);
if (Base::level_stack_.Empty()) // end of json text
Base::os_->Flush();
return true;
}
//@}
/*! @name Convenience extensions */
//@{
//! Simpler but slower overload.
bool String(const Ch* str) { return String(str, internal::StrLen(str)); }
bool Key(const Ch* str) { return Key(str, internal::StrLen(str)); }
//@}
protected:
void PrettyPrefix(Type type) {
(void)type;
if (Base::level_stack_.GetSize() != 0) { // this value is not at root
typename Base::Level* level = Base::level_stack_.template Top<typename Base::Level>();
if (level->inArray) {
if (level->valueCount > 0) {
Base::os_->Put(','); // add comma if it is not the first element in array
Base::os_->Put('\n');
}
else
Base::os_->Put('\n');
WriteIndent();
}
else { // in object
if (level->valueCount > 0) {
if (level->valueCount % 2 == 0) {
Base::os_->Put(',');
Base::os_->Put('\n');
}
else {
Base::os_->Put(':');
Base::os_->Put(' ');
}
}
else
Base::os_->Put('\n');
if (level->valueCount % 2 == 0)
WriteIndent();
}
if (!level->inArray && level->valueCount % 2 == 0)
RAPIDJSON_ASSERT(type == kStringType); // if it's in object, then even number should be a name
level->valueCount++;
}
else {
RAPIDJSON_ASSERT(!Base::hasRoot_); // Should only has one and only one root.
Base::hasRoot_ = true;
}
}
void WriteIndent() {
size_t count = (Base::level_stack_.GetSize() / sizeof(typename Base::Level)) * indentCharCount_;
PutN(*Base::os_, indentChar_, count);
}
Ch indentChar_;
unsigned indentCharCount_;
private:
// Prohibit copy constructor & assignment operator.
PrettyWriter(const PrettyWriter&);
PrettyWriter& operator=(const PrettyWriter&);
};
RAPIDJSON_NAMESPACE_END
#ifdef __GNUC__
RAPIDJSON_DIAG_POP
#endif
#endif // RAPIDJSON_RAPIDJSON_H_
+620
Ver Arquivo
@@ -0,0 +1,620 @@
// Tencent is pleased to support the open source community by making RapidJSON available.
//
// Copyright (C) 2015 THL A29 Limited, a Tencent company, and Milo Yip. All rights reserved.
//
// Licensed under the MIT License (the "License"); you may not use this file except
// in compliance with the License. You may obtain a copy of the License at
//
// http://opensource.org/licenses/MIT
//
// Unless required by applicable law or agreed to in writing, software distributed
// under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
// CONDITIONS OF ANY KIND, either express or implied. See the License for the
// specific language governing permissions and limitations under the License.
#ifndef RAPIDJSON_RAPIDJSON_H_
#define RAPIDJSON_RAPIDJSON_H_
/*!\file rapidjson.h
\brief common definitions and configuration
\see RAPIDJSON_CONFIG
*/
/*! \defgroup RAPIDJSON_CONFIG RapidJSON configuration
\brief Configuration macros for library features
Some RapidJSON features are configurable to adapt the library to a wide
variety of platforms, environments and usage scenarios. Most of the
features can be configured in terms of overriden or predefined
preprocessor macros at compile-time.
Some additional customization is available in the \ref RAPIDJSON_ERRORS APIs.
\note These macros should be given on the compiler command-line
(where applicable) to avoid inconsistent values when compiling
different translation units of a single application.
*/
#include <cstdlib> // malloc(), realloc(), free(), size_t
#include <cstring> // memset(), memcpy(), memmove(), memcmp()
///////////////////////////////////////////////////////////////////////////////
// RAPIDJSON_NAMESPACE_(BEGIN|END)
/*! \def RAPIDJSON_NAMESPACE
\ingroup RAPIDJSON_CONFIG
\brief provide custom rapidjson namespace
In order to avoid symbol clashes and/or "One Definition Rule" errors
between multiple inclusions of (different versions of) RapidJSON in
a single binary, users can customize the name of the main RapidJSON
namespace.
In case of a single nesting level, defining \c RAPIDJSON_NAMESPACE
to a custom name (e.g. \c MyRapidJSON) is sufficient. If multiple
levels are needed, both \ref RAPIDJSON_NAMESPACE_BEGIN and \ref
RAPIDJSON_NAMESPACE_END need to be defined as well:
\code
// in some .cpp file
#define RAPIDJSON_NAMESPACE my::rapidjson
#define RAPIDJSON_NAMESPACE_BEGIN namespace my { namespace rapidjson {
#define RAPIDJSON_NAMESPACE_END } }
#include "rapidjson/..."
\endcode
\see rapidjson
*/
/*! \def RAPIDJSON_NAMESPACE_BEGIN
\ingroup RAPIDJSON_CONFIG
\brief provide custom rapidjson namespace (opening expression)
\see RAPIDJSON_NAMESPACE
*/
/*! \def RAPIDJSON_NAMESPACE_END
\ingroup RAPIDJSON_CONFIG
\brief provide custom rapidjson namespace (closing expression)
\see RAPIDJSON_NAMESPACE
*/
#ifndef RAPIDJSON_NAMESPACE
#define RAPIDJSON_NAMESPACE rapidjson
#endif
#ifndef RAPIDJSON_NAMESPACE_BEGIN
#define RAPIDJSON_NAMESPACE_BEGIN namespace RAPIDJSON_NAMESPACE {
#endif
#ifndef RAPIDJSON_NAMESPACE_END
#define RAPIDJSON_NAMESPACE_END }
#endif
///////////////////////////////////////////////////////////////////////////////
// RAPIDJSON_NO_INT64DEFINE
/*! \def RAPIDJSON_NO_INT64DEFINE
\ingroup RAPIDJSON_CONFIG
\brief Use external 64-bit integer types.
RapidJSON requires the 64-bit integer types \c int64_t and \c uint64_t types
to be available at global scope.
If users have their own definition, define RAPIDJSON_NO_INT64DEFINE to
prevent RapidJSON from defining its own types.
*/
#ifndef RAPIDJSON_NO_INT64DEFINE
//!@cond RAPIDJSON_HIDDEN_FROM_DOXYGEN
#ifdef _MSC_VER
#include "msinttypes/stdint.h"
#include "msinttypes/inttypes.h"
#else
// Other compilers should have this.
#include <stdint.h>
#include <inttypes.h>
#endif
//!@endcond
#ifdef RAPIDJSON_DOXYGEN_RUNNING
#define RAPIDJSON_NO_INT64DEFINE
#endif
#endif // RAPIDJSON_NO_INT64TYPEDEF
///////////////////////////////////////////////////////////////////////////////
// RAPIDJSON_FORCEINLINE
#ifndef RAPIDJSON_FORCEINLINE
//!@cond RAPIDJSON_HIDDEN_FROM_DOXYGEN
#if defined(_MSC_VER) && !defined(NDEBUG)
#define RAPIDJSON_FORCEINLINE __forceinline
#elif defined(__GNUC__) && __GNUC__ >= 4 && !defined(NDEBUG)
#define RAPIDJSON_FORCEINLINE __attribute__((always_inline))
#else
#define RAPIDJSON_FORCEINLINE
#endif
//!@endcond
#endif // RAPIDJSON_FORCEINLINE
///////////////////////////////////////////////////////////////////////////////
// RAPIDJSON_ENDIAN
#define RAPIDJSON_LITTLEENDIAN 0 //!< Little endian machine
#define RAPIDJSON_BIGENDIAN 1 //!< Big endian machine
//! Endianness of the machine.
/*!
\def RAPIDJSON_ENDIAN
\ingroup RAPIDJSON_CONFIG
GCC 4.6 provided macro for detecting endianness of the target machine. But other
compilers may not have this. User can define RAPIDJSON_ENDIAN to either
\ref RAPIDJSON_LITTLEENDIAN or \ref RAPIDJSON_BIGENDIAN.
Default detection implemented with reference to
\li https://gcc.gnu.org/onlinedocs/gcc-4.6.0/cpp/Common-Predefined-Macros.html
\li http://www.boost.org/doc/libs/1_42_0/boost/detail/endian.hpp
*/
#ifndef RAPIDJSON_ENDIAN
// Detect with GCC 4.6's macro
# ifdef __BYTE_ORDER__
# if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__
# define RAPIDJSON_ENDIAN RAPIDJSON_LITTLEENDIAN
# elif __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__
# define RAPIDJSON_ENDIAN RAPIDJSON_BIGENDIAN
# else
# error Unknown machine endianess detected. User needs to define RAPIDJSON_ENDIAN.
# endif // __BYTE_ORDER__
// Detect with GLIBC's endian.h
# elif defined(__GLIBC__)
# include <endian.h>
# if (__BYTE_ORDER == __LITTLE_ENDIAN)
# define RAPIDJSON_ENDIAN RAPIDJSON_LITTLEENDIAN
# elif (__BYTE_ORDER == __BIG_ENDIAN)
# define RAPIDJSON_ENDIAN RAPIDJSON_BIGENDIAN
# else
# error Unknown machine endianess detected. User needs to define RAPIDJSON_ENDIAN.
# endif // __GLIBC__
// Detect with _LITTLE_ENDIAN and _BIG_ENDIAN macro
# elif defined(_LITTLE_ENDIAN) && !defined(_BIG_ENDIAN)
# define RAPIDJSON_ENDIAN RAPIDJSON_LITTLEENDIAN
# elif defined(_BIG_ENDIAN) && !defined(_LITTLE_ENDIAN)
# define RAPIDJSON_ENDIAN RAPIDJSON_BIGENDIAN
// Detect with architecture macros
# elif defined(__sparc) || defined(__sparc__) || defined(_POWER) || defined(__powerpc__) || defined(__ppc__) || defined(__hpux) || defined(__hppa) || defined(_MIPSEB) || defined(_POWER) || defined(__s390__)
# define RAPIDJSON_ENDIAN RAPIDJSON_BIGENDIAN
# elif defined(__i386__) || defined(__alpha__) || defined(__ia64) || defined(__ia64__) || defined(_M_IX86) || defined(_M_IA64) || defined(_M_ALPHA) || defined(__amd64) || defined(__amd64__) || defined(_M_AMD64) || defined(__x86_64) || defined(__x86_64__) || defined(_M_X64) || defined(__bfin__)
# define RAPIDJSON_ENDIAN RAPIDJSON_LITTLEENDIAN
# elif defined(RAPIDJSON_DOXYGEN_RUNNING)
# define RAPIDJSON_ENDIAN
# else
# error Unknown machine endianess detected. User needs to define RAPIDJSON_ENDIAN.
# endif
#endif // RAPIDJSON_ENDIAN
///////////////////////////////////////////////////////////////////////////////
// RAPIDJSON_64BIT
//! Whether using 64-bit architecture
#ifndef RAPIDJSON_64BIT
#if defined(__LP64__) || defined(_WIN64)
#define RAPIDJSON_64BIT 1
#else
#define RAPIDJSON_64BIT 0
#endif
#endif // RAPIDJSON_64BIT
///////////////////////////////////////////////////////////////////////////////
// RAPIDJSON_ALIGN
//! Data alignment of the machine.
/*! \ingroup RAPIDJSON_CONFIG
\param x pointer to align
Some machines require strict data alignment. Currently the default uses 4 bytes
alignment. User can customize by defining the RAPIDJSON_ALIGN function macro.,
*/
#ifndef RAPIDJSON_ALIGN
#define RAPIDJSON_ALIGN(x) ((x + 3u) & ~3u)
#endif
///////////////////////////////////////////////////////////////////////////////
// RAPIDJSON_UINT64_C2
//! Construct a 64-bit literal by a pair of 32-bit integer.
/*!
64-bit literal with or without ULL suffix is prone to compiler warnings.
UINT64_C() is C macro which cause compilation problems.
Use this macro to define 64-bit constants by a pair of 32-bit integer.
*/
#ifndef RAPIDJSON_UINT64_C2
#define RAPIDJSON_UINT64_C2(high32, low32) ((static_cast<uint64_t>(high32) << 32) | static_cast<uint64_t>(low32))
#endif
///////////////////////////////////////////////////////////////////////////////
// RAPIDJSON_SSE2/RAPIDJSON_SSE42/RAPIDJSON_SIMD
/*! \def RAPIDJSON_SIMD
\ingroup RAPIDJSON_CONFIG
\brief Enable SSE2/SSE4.2 optimization.
RapidJSON supports optimized implementations for some parsing operations
based on the SSE2 or SSE4.2 SIMD extensions on modern Intel-compatible
processors.
To enable these optimizations, two different symbols can be defined;
\code
// Enable SSE2 optimization.
#define RAPIDJSON_SSE2
// Enable SSE4.2 optimization.
#define RAPIDJSON_SSE42
\endcode
\c RAPIDJSON_SSE42 takes precedence, if both are defined.
If any of these symbols is defined, RapidJSON defines the macro
\c RAPIDJSON_SIMD to indicate the availability of the optimized code.
*/
#if defined(RAPIDJSON_SSE2) || defined(RAPIDJSON_SSE42) \
|| defined(RAPIDJSON_DOXYGEN_RUNNING)
#define RAPIDJSON_SIMD
#endif
///////////////////////////////////////////////////////////////////////////////
// RAPIDJSON_NO_SIZETYPEDEFINE
#ifndef RAPIDJSON_NO_SIZETYPEDEFINE
/*! \def RAPIDJSON_NO_SIZETYPEDEFINE
\ingroup RAPIDJSON_CONFIG
\brief User-provided \c SizeType definition.
In order to avoid using 32-bit size types for indexing strings and arrays,
define this preprocessor symbol and provide the type rapidjson::SizeType
before including RapidJSON:
\code
#define RAPIDJSON_NO_SIZETYPEDEFINE
namespace rapidjson { typedef ::std::size_t SizeType; }
#include "rapidjson/..."
\endcode
\see rapidjson::SizeType
*/
#ifdef RAPIDJSON_DOXYGEN_RUNNING
#define RAPIDJSON_NO_SIZETYPEDEFINE
#endif
RAPIDJSON_NAMESPACE_BEGIN
//! Size type (for string lengths, array sizes, etc.)
/*! RapidJSON uses 32-bit array/string indices even on 64-bit platforms,
instead of using \c size_t. Users may override the SizeType by defining
\ref RAPIDJSON_NO_SIZETYPEDEFINE.
*/
typedef unsigned SizeType;
RAPIDJSON_NAMESPACE_END
#endif
// always import std::size_t to rapidjson namespace
RAPIDJSON_NAMESPACE_BEGIN
using std::size_t;
RAPIDJSON_NAMESPACE_END
///////////////////////////////////////////////////////////////////////////////
// RAPIDJSON_ASSERT
//! Assertion.
/*! \ingroup RAPIDJSON_CONFIG
By default, rapidjson uses C \c assert() for internal assertions.
User can override it by defining RAPIDJSON_ASSERT(x) macro.
\note Parsing errors are handled and can be customized by the
\ref RAPIDJSON_ERRORS APIs.
*/
#ifndef RAPIDJSON_ASSERT
#include <cassert>
#define RAPIDJSON_ASSERT(x) assert(x)
#endif // RAPIDJSON_ASSERT
///////////////////////////////////////////////////////////////////////////////
// RAPIDJSON_STATIC_ASSERT
// Adopt from boost
#ifndef RAPIDJSON_STATIC_ASSERT
//!@cond RAPIDJSON_HIDDEN_FROM_DOXYGEN
RAPIDJSON_NAMESPACE_BEGIN
template <bool x> struct STATIC_ASSERTION_FAILURE;
template <> struct STATIC_ASSERTION_FAILURE<true> { enum { value = 1 }; };
template<int x> struct StaticAssertTest {};
RAPIDJSON_NAMESPACE_END
#define RAPIDJSON_JOIN(X, Y) RAPIDJSON_DO_JOIN(X, Y)
#define RAPIDJSON_DO_JOIN(X, Y) RAPIDJSON_DO_JOIN2(X, Y)
#define RAPIDJSON_DO_JOIN2(X, Y) X##Y
#if defined(__GNUC__)
#define RAPIDJSON_STATIC_ASSERT_UNUSED_ATTRIBUTE __attribute__((unused))
#else
#define RAPIDJSON_STATIC_ASSERT_UNUSED_ATTRIBUTE
#endif
//!@endcond
/*! \def RAPIDJSON_STATIC_ASSERT
\brief (Internal) macro to check for conditions at compile-time
\param x compile-time condition
\hideinitializer
*/
#define RAPIDJSON_STATIC_ASSERT(x) \
typedef ::RAPIDJSON_NAMESPACE::StaticAssertTest< \
sizeof(::RAPIDJSON_NAMESPACE::STATIC_ASSERTION_FAILURE<bool(x) >)> \
RAPIDJSON_JOIN(StaticAssertTypedef, __LINE__) RAPIDJSON_STATIC_ASSERT_UNUSED_ATTRIBUTE
#endif
///////////////////////////////////////////////////////////////////////////////
// Helpers
//!@cond RAPIDJSON_HIDDEN_FROM_DOXYGEN
#define RAPIDJSON_MULTILINEMACRO_BEGIN do {
#define RAPIDJSON_MULTILINEMACRO_END \
} while((void)0, 0)
// adopted from Boost
#define RAPIDJSON_VERSION_CODE(x,y,z) \
(((x)*100000) + ((y)*100) + (z))
// token stringification
#define RAPIDJSON_STRINGIFY(x) RAPIDJSON_DO_STRINGIFY(x)
#define RAPIDJSON_DO_STRINGIFY(x) #x
///////////////////////////////////////////////////////////////////////////////
// RAPIDJSON_DIAG_PUSH/POP, RAPIDJSON_DIAG_OFF
#if defined(__GNUC__)
#define RAPIDJSON_GNUC \
RAPIDJSON_VERSION_CODE(__GNUC__,__GNUC_MINOR__,__GNUC_PATCHLEVEL__)
#endif
#if defined(__clang__) || (defined(RAPIDJSON_GNUC) && RAPIDJSON_GNUC >= RAPIDJSON_VERSION_CODE(4,2,0))
#define RAPIDJSON_PRAGMA(x) _Pragma(RAPIDJSON_STRINGIFY(x))
#define RAPIDJSON_DIAG_PRAGMA(x) RAPIDJSON_PRAGMA(GCC diagnostic x)
#define RAPIDJSON_DIAG_OFF(x) \
RAPIDJSON_DIAG_PRAGMA(ignored RAPIDJSON_STRINGIFY(RAPIDJSON_JOIN(-W,x)))
// push/pop support in Clang and GCC>=4.6
#if defined(__clang__) || (defined(RAPIDJSON_GNUC) && RAPIDJSON_GNUC >= RAPIDJSON_VERSION_CODE(4,6,0))
#define RAPIDJSON_DIAG_PUSH RAPIDJSON_DIAG_PRAGMA(push)
#define RAPIDJSON_DIAG_POP RAPIDJSON_DIAG_PRAGMA(pop)
#else // GCC >= 4.2, < 4.6
#define RAPIDJSON_DIAG_PUSH /* ignored */
#define RAPIDJSON_DIAG_POP /* ignored */
#endif
#elif defined(_MSC_VER)
// pragma (MSVC specific)
#define RAPIDJSON_PRAGMA(x) __pragma(x)
#define RAPIDJSON_DIAG_PRAGMA(x) RAPIDJSON_PRAGMA(warning(x))
#define RAPIDJSON_DIAG_OFF(x) RAPIDJSON_DIAG_PRAGMA(disable: x)
#define RAPIDJSON_DIAG_PUSH RAPIDJSON_DIAG_PRAGMA(push)
#define RAPIDJSON_DIAG_POP RAPIDJSON_DIAG_PRAGMA(pop)
#else
#define RAPIDJSON_DIAG_OFF(x) /* ignored */
#define RAPIDJSON_DIAG_PUSH /* ignored */
#define RAPIDJSON_DIAG_POP /* ignored */
#endif // RAPIDJSON_DIAG_*
///////////////////////////////////////////////////////////////////////////////
// C++11 features
#ifndef RAPIDJSON_HAS_CXX11_RVALUE_REFS
#if defined(__clang__)
#define RAPIDJSON_HAS_CXX11_RVALUE_REFS __has_feature(cxx_rvalue_references) && \
(defined(_LIBCPP_VERSION) || defined(__GLIBCXX__) && __GLIBCXX__ >= 20080306)
#elif (defined(RAPIDJSON_GNUC) && (RAPIDJSON_GNUC >= RAPIDJSON_VERSION_CODE(4,3,0)) && defined(__GXX_EXPERIMENTAL_CXX0X__)) || \
(defined(_MSC_VER) && _MSC_VER >= 1600)
#define RAPIDJSON_HAS_CXX11_RVALUE_REFS 1
#else
#define RAPIDJSON_HAS_CXX11_RVALUE_REFS 0
#endif
#endif // RAPIDJSON_HAS_CXX11_RVALUE_REFS
#ifndef RAPIDJSON_HAS_CXX11_NOEXCEPT
#if defined(__clang__)
#define RAPIDJSON_HAS_CXX11_NOEXCEPT __has_feature(cxx_noexcept)
#elif (defined(RAPIDJSON_GNUC) && (RAPIDJSON_GNUC >= RAPIDJSON_VERSION_CODE(4,6,0)) && defined(__GXX_EXPERIMENTAL_CXX0X__))
// (defined(_MSC_VER) && _MSC_VER >= ????) // not yet supported
#define RAPIDJSON_HAS_CXX11_NOEXCEPT 1
#else
#define RAPIDJSON_HAS_CXX11_NOEXCEPT 0
#endif
#endif
#if RAPIDJSON_HAS_CXX11_NOEXCEPT
#define RAPIDJSON_NOEXCEPT noexcept
#else
#define RAPIDJSON_NOEXCEPT /* noexcept */
#endif // RAPIDJSON_HAS_CXX11_NOEXCEPT
// no automatic detection, yet
#ifndef RAPIDJSON_HAS_CXX11_TYPETRAITS
#define RAPIDJSON_HAS_CXX11_TYPETRAITS 0
#endif
//!@endcond
///////////////////////////////////////////////////////////////////////////////
// new/delete
#ifndef RAPIDJSON_NEW
///! customization point for global \c new
#define RAPIDJSON_NEW(x) new x
#endif
#ifndef RAPIDJSON_DELETE
///! customization point for global \c delete
#define RAPIDJSON_DELETE(x) delete x
#endif
///////////////////////////////////////////////////////////////////////////////
// Allocators and Encodings
#include "allocators.h"
#include "encodings.h"
/*! \namespace rapidjson
\brief main RapidJSON namespace
\see RAPIDJSON_NAMESPACE
*/
RAPIDJSON_NAMESPACE_BEGIN
///////////////////////////////////////////////////////////////////////////////
// Stream
/*! \class rapidjson::Stream
\brief Concept for reading and writing characters.
For read-only stream, no need to implement PutBegin(), Put(), Flush() and PutEnd().
For write-only stream, only need to implement Put() and Flush().
\code
concept Stream {
typename Ch; //!< Character type of the stream.
//! Read the current character from stream without moving the read cursor.
Ch Peek() const;
//! Read the current character from stream and moving the read cursor to next character.
Ch Take();
//! Get the current read cursor.
//! \return Number of characters read from start.
size_t Tell();
//! Begin writing operation at the current read pointer.
//! \return The begin writer pointer.
Ch* PutBegin();
//! Write a character.
void Put(Ch c);
//! Flush the buffer.
void Flush();
//! End the writing operation.
//! \param begin The begin write pointer returned by PutBegin().
//! \return Number of characters written.
size_t PutEnd(Ch* begin);
}
\endcode
*/
//! Provides additional information for stream.
/*!
By using traits pattern, this type provides a default configuration for stream.
For custom stream, this type can be specialized for other configuration.
See TEST(Reader, CustomStringStream) in readertest.cpp for example.
*/
template<typename Stream>
struct StreamTraits {
//! Whether to make local copy of stream for optimization during parsing.
/*!
By default, for safety, streams do not use local copy optimization.
Stream that can be copied fast should specialize this, like StreamTraits<StringStream>.
*/
enum { copyOptimization = 0 };
};
//! Put N copies of a character to a stream.
template<typename Stream, typename Ch>
inline void PutN(Stream& stream, Ch c, size_t n) {
for (size_t i = 0; i < n; i++)
stream.Put(c);
}
///////////////////////////////////////////////////////////////////////////////
// StringStream
//! Read-only string stream.
/*! \note implements Stream concept
*/
template <typename Encoding>
struct GenericStringStream {
typedef typename Encoding::Ch Ch;
GenericStringStream(const Ch *src) : src_(src), head_(src) {}
Ch Peek() const { return *src_; }
Ch Take() { return *src_++; }
size_t Tell() const { return static_cast<size_t>(src_ - head_); }
Ch* PutBegin() { RAPIDJSON_ASSERT(false); return 0; }
void Put(Ch) { RAPIDJSON_ASSERT(false); }
void Flush() { RAPIDJSON_ASSERT(false); }
size_t PutEnd(Ch*) { RAPIDJSON_ASSERT(false); return 0; }
const Ch* src_; //!< Current read position.
const Ch* head_; //!< Original head of the string.
};
template <typename Encoding>
struct StreamTraits<GenericStringStream<Encoding> > {
enum { copyOptimization = 1 };
};
//! String stream with UTF8 encoding.
typedef GenericStringStream<UTF8<> > StringStream;
///////////////////////////////////////////////////////////////////////////////
// InsituStringStream
//! A read-write string stream.
/*! This string stream is particularly designed for in-situ parsing.
\note implements Stream concept
*/
template <typename Encoding>
struct GenericInsituStringStream {
typedef typename Encoding::Ch Ch;
GenericInsituStringStream(Ch *src) : src_(src), dst_(0), head_(src) {}
// Read
Ch Peek() { return *src_; }
Ch Take() { return *src_++; }
size_t Tell() { return static_cast<size_t>(src_ - head_); }
// Write
void Put(Ch c) { RAPIDJSON_ASSERT(dst_ != 0); *dst_++ = c; }
Ch* PutBegin() { return dst_ = src_; }
size_t PutEnd(Ch* begin) { return static_cast<size_t>(dst_ - begin); }
void Flush() {}
Ch* Push(size_t count) { Ch* begin = dst_; dst_ += count; return begin; }
void Pop(size_t count) { dst_ -= count; }
Ch* src_;
Ch* dst_;
Ch* head_;
};
template <typename Encoding>
struct StreamTraits<GenericInsituStringStream<Encoding> > {
enum { copyOptimization = 1 };
};
//! Insitu string stream with UTF8 encoding.
typedef GenericInsituStringStream<UTF8<> > InsituStringStream;
///////////////////////////////////////////////////////////////////////////////
// Type
//! Type of JSON value
enum Type {
kNullType = 0, //!< null
kFalseType = 1, //!< false
kTrueType = 2, //!< true
kObjectType = 3, //!< object
kArrayType = 4, //!< array
kStringType = 5, //!< string
kNumberType = 6 //!< number
};
RAPIDJSON_NAMESPACE_END
#endif // RAPIDJSON_RAPIDJSON_H_
Diferenças do arquivo suprimidas por serem muito extensas Carregar Diff
+93
Ver Arquivo
@@ -0,0 +1,93 @@
// Tencent is pleased to support the open source community by making RapidJSON available.
//
// Copyright (C) 2015 THL A29 Limited, a Tencent company, and Milo Yip. All rights reserved.
//
// Licensed under the MIT License (the "License"); you may not use this file except
// in compliance with the License. You may obtain a copy of the License at
//
// http://opensource.org/licenses/MIT
//
// Unless required by applicable law or agreed to in writing, software distributed
// under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
// CONDITIONS OF ANY KIND, either express or implied. See the License for the
// specific language governing permissions and limitations under the License.
#ifndef RAPIDJSON_STRINGBUFFER_H_
#define RAPIDJSON_STRINGBUFFER_H_
#include "rapidjson.h"
#if RAPIDJSON_HAS_CXX11_RVALUE_REFS
#include <utility> // std::move
#endif
#include "internal/stack.h"
RAPIDJSON_NAMESPACE_BEGIN
//! Represents an in-memory output stream.
/*!
\tparam Encoding Encoding of the stream.
\tparam Allocator type for allocating memory buffer.
\note implements Stream concept
*/
template <typename Encoding, typename Allocator = CrtAllocator>
class GenericStringBuffer {
public:
typedef typename Encoding::Ch Ch;
GenericStringBuffer(Allocator* allocator = 0, size_t capacity = kDefaultCapacity) : stack_(allocator, capacity) {}
#if RAPIDJSON_HAS_CXX11_RVALUE_REFS
GenericStringBuffer(GenericStringBuffer&& rhs) : stack_(std::move(rhs.stack_)) {}
GenericStringBuffer& operator=(GenericStringBuffer&& rhs) {
if (&rhs != this)
stack_ = std::move(rhs.stack_);
return *this;
}
#endif
void Put(Ch c) { *stack_.template Push<Ch>() = c; }
void Flush() {}
void Clear() { stack_.Clear(); }
void ShrinkToFit() {
// Push and pop a null terminator. This is safe.
*stack_.template Push<Ch>() = '\0';
stack_.ShrinkToFit();
stack_.template Pop<Ch>(1);
}
Ch* Push(size_t count) { return stack_.template Push<Ch>(count); }
void Pop(size_t count) { stack_.template Pop<Ch>(count); }
const Ch* GetString() const {
// Push and pop a null terminator. This is safe.
*stack_.template Push<Ch>() = '\0';
stack_.template Pop<Ch>(1);
return stack_.template Bottom<Ch>();
}
size_t GetSize() const { return stack_.GetSize(); }
static const size_t kDefaultCapacity = 256;
mutable internal::Stack<Allocator> stack_;
private:
// Prohibit copy constructor & assignment operator.
GenericStringBuffer(const GenericStringBuffer&);
GenericStringBuffer& operator=(const GenericStringBuffer&);
};
//! String buffer with UTF8 encoding
typedef GenericStringBuffer<UTF8<> > StringBuffer;
//! Implement specialized version of PutN() with memset() for better performance.
template<>
inline void PutN(GenericStringBuffer<UTF8<> >& stream, char c, size_t n) {
std::memset(stream.stack_.Push<char>(n), c, n * sizeof(c));
}
RAPIDJSON_NAMESPACE_END
#endif // RAPIDJSON_STRINGBUFFER_H_
+395
Ver Arquivo
@@ -0,0 +1,395 @@
// Tencent is pleased to support the open source community by making RapidJSON available.
//
// Copyright (C) 2015 THL A29 Limited, a Tencent company, and Milo Yip. All rights reserved.
//
// Licensed under the MIT License (the "License"); you may not use this file except
// in compliance with the License. You may obtain a copy of the License at
//
// http://opensource.org/licenses/MIT
//
// Unless required by applicable law or agreed to in writing, software distributed
// under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
// CONDITIONS OF ANY KIND, either express or implied. See the License for the
// specific language governing permissions and limitations under the License.
#ifndef RAPIDJSON_WRITER_H_
#define RAPIDJSON_WRITER_H_
#include "rapidjson.h"
#include "internal/stack.h"
#include "internal/strfunc.h"
#include "internal/dtoa.h"
#include "internal/itoa.h"
#include "stringbuffer.h"
#include <new> // placement new
#if RAPIDJSON_HAS_STDSTRING
#include <string>
#endif
#ifdef _MSC_VER
RAPIDJSON_DIAG_PUSH
RAPIDJSON_DIAG_OFF(4127) // conditional expression is constant
#endif
RAPIDJSON_NAMESPACE_BEGIN
//! JSON writer
/*! Writer implements the concept Handler.
It generates JSON text by events to an output os.
User may programmatically calls the functions of a writer to generate JSON text.
On the other side, a writer can also be passed to objects that generates events,
for example Reader::Parse() and Document::Accept().
\tparam OutputStream Type of output stream.
\tparam SourceEncoding Encoding of source string.
\tparam TargetEncoding Encoding of output stream.
\tparam StackAllocator Type of allocator for allocating memory of stack.
\note implements Handler concept
*/
template<typename OutputStream, typename SourceEncoding = UTF8<>, typename TargetEncoding = UTF8<>, typename StackAllocator = CrtAllocator>
class Writer {
public:
typedef typename SourceEncoding::Ch Ch;
//! Constructor
/*! \param os Output stream.
\param stackAllocator User supplied allocator. If it is null, it will create a private one.
\param levelDepth Initial capacity of stack.
*/
explicit
Writer(OutputStream& os, StackAllocator* stackAllocator = 0, size_t levelDepth = kDefaultLevelDepth) :
os_(&os), level_stack_(stackAllocator, levelDepth * sizeof(Level)), hasRoot_(false) {}
explicit
Writer(StackAllocator* allocator = 0, size_t levelDepth = kDefaultLevelDepth) :
os_(0), level_stack_(allocator, levelDepth * sizeof(Level)), hasRoot_(false) {}
//! Reset the writer with a new stream.
/*!
This function reset the writer with a new stream and default settings,
in order to make a Writer object reusable for output multiple JSONs.
\param os New output stream.
\code
Writer<OutputStream> writer(os1);
writer.StartObject();
// ...
writer.EndObject();
writer.Reset(os2);
writer.StartObject();
// ...
writer.EndObject();
\endcode
*/
void Reset(OutputStream& os) {
os_ = &os;
hasRoot_ = false;
level_stack_.Clear();
}
//! Checks whether the output is a complete JSON.
/*!
A complete JSON has a complete root object or array.
*/
bool IsComplete() const {
return hasRoot_ && level_stack_.Empty();
}
/*!@name Implementation of Handler
\see Handler
*/
//@{
bool Null() { Prefix(kNullType); return WriteNull(); }
bool Bool(bool b) { Prefix(b ? kTrueType : kFalseType); return WriteBool(b); }
bool Int(int i) { Prefix(kNumberType); return WriteInt(i); }
bool Uint(unsigned u) { Prefix(kNumberType); return WriteUint(u); }
bool Int64(int64_t i64) { Prefix(kNumberType); return WriteInt64(i64); }
bool Uint64(uint64_t u64) { Prefix(kNumberType); return WriteUint64(u64); }
//! Writes the given \c double value to the stream
/*!
\param d The value to be written.
\return Whether it is succeed.
*/
bool Double(double d) { Prefix(kNumberType); return WriteDouble(d); }
bool String(const Ch* str, SizeType length, bool copy = false) {
(void)copy;
Prefix(kStringType);
return WriteString(str, length);
}
#if RAPIDJSON_HAS_STDSTRING
bool String(const std::basic_string<Ch>& str) {
return String(str.data(), SizeType(str.size()));
}
#endif
bool StartObject() {
Prefix(kObjectType);
new (level_stack_.template Push<Level>()) Level(false);
return WriteStartObject();
}
bool Key(const Ch* str, SizeType length, bool copy = false) { return String(str, length, copy); }
bool EndObject(SizeType memberCount = 0) {
(void)memberCount;
RAPIDJSON_ASSERT(level_stack_.GetSize() >= sizeof(Level));
RAPIDJSON_ASSERT(!level_stack_.template Top<Level>()->inArray);
level_stack_.template Pop<Level>(1);
bool ret = WriteEndObject();
if (level_stack_.Empty()) // end of json text
os_->Flush();
return ret;
}
bool StartArray() {
Prefix(kArrayType);
new (level_stack_.template Push<Level>()) Level(true);
return WriteStartArray();
}
bool EndArray(SizeType elementCount = 0) {
(void)elementCount;
RAPIDJSON_ASSERT(level_stack_.GetSize() >= sizeof(Level));
RAPIDJSON_ASSERT(level_stack_.template Top<Level>()->inArray);
level_stack_.template Pop<Level>(1);
bool ret = WriteEndArray();
if (level_stack_.Empty()) // end of json text
os_->Flush();
return ret;
}
//@}
/*! @name Convenience extensions */
//@{
//! Simpler but slower overload.
bool String(const Ch* str) { return String(str, internal::StrLen(str)); }
bool Key(const Ch* str) { return Key(str, internal::StrLen(str)); }
//@}
protected:
//! Information for each nested level
struct Level {
Level(bool inArray_) : valueCount(0), inArray(inArray_) {}
size_t valueCount; //!< number of values in this level
bool inArray; //!< true if in array, otherwise in object
};
static const size_t kDefaultLevelDepth = 32;
bool WriteNull() {
os_->Put('n'); os_->Put('u'); os_->Put('l'); os_->Put('l'); return true;
}
bool WriteBool(bool b) {
if (b) {
os_->Put('t'); os_->Put('r'); os_->Put('u'); os_->Put('e');
}
else {
os_->Put('f'); os_->Put('a'); os_->Put('l'); os_->Put('s'); os_->Put('e');
}
return true;
}
bool WriteInt(int i) {
char buffer[11];
const char* end = internal::i32toa(i, buffer);
for (const char* p = buffer; p != end; ++p)
os_->Put(*p);
return true;
}
bool WriteUint(unsigned u) {
char buffer[10];
const char* end = internal::u32toa(u, buffer);
for (const char* p = buffer; p != end; ++p)
os_->Put(*p);
return true;
}
bool WriteInt64(int64_t i64) {
char buffer[21];
const char* end = internal::i64toa(i64, buffer);
for (const char* p = buffer; p != end; ++p)
os_->Put(*p);
return true;
}
bool WriteUint64(uint64_t u64) {
char buffer[20];
char* end = internal::u64toa(u64, buffer);
for (char* p = buffer; p != end; ++p)
os_->Put(*p);
return true;
}
bool WriteDouble(double d) {
char buffer[25];
char* end = internal::dtoa(d, buffer);
for (char* p = buffer; p != end; ++p)
os_->Put(*p);
return true;
}
bool WriteString(const Ch* str, SizeType length) {
static const char hexDigits[16] = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F' };
static const char escape[256] = {
#define Z16 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
//0 1 2 3 4 5 6 7 8 9 A B C D E F
'u', 'u', 'u', 'u', 'u', 'u', 'u', 'u', 'b', 't', 'n', 'u', 'f', 'r', 'u', 'u', // 00
'u', 'u', 'u', 'u', 'u', 'u', 'u', 'u', 'u', 'u', 'u', 'u', 'u', 'u', 'u', 'u', // 10
0, 0, '"', 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 20
Z16, Z16, // 30~4F
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,'\\', 0, 0, 0, // 50
Z16, Z16, Z16, Z16, Z16, Z16, Z16, Z16, Z16, Z16 // 60~FF
#undef Z16
};
os_->Put('\"');
GenericStringStream<SourceEncoding> is(str);
while (is.Tell() < length) {
const Ch c = is.Peek();
if (!TargetEncoding::supportUnicode && (unsigned)c >= 0x80) {
// Unicode escaping
unsigned codepoint;
if (!SourceEncoding::Decode(is, &codepoint))
return false;
os_->Put('\\');
os_->Put('u');
if (codepoint <= 0xD7FF || (codepoint >= 0xE000 && codepoint <= 0xFFFF)) {
os_->Put(hexDigits[(codepoint >> 12) & 15]);
os_->Put(hexDigits[(codepoint >> 8) & 15]);
os_->Put(hexDigits[(codepoint >> 4) & 15]);
os_->Put(hexDigits[(codepoint ) & 15]);
}
else {
RAPIDJSON_ASSERT(codepoint >= 0x010000 && codepoint <= 0x10FFFF);
// Surrogate pair
unsigned s = codepoint - 0x010000;
unsigned lead = (s >> 10) + 0xD800;
unsigned trail = (s & 0x3FF) + 0xDC00;
os_->Put(hexDigits[(lead >> 12) & 15]);
os_->Put(hexDigits[(lead >> 8) & 15]);
os_->Put(hexDigits[(lead >> 4) & 15]);
os_->Put(hexDigits[(lead ) & 15]);
os_->Put('\\');
os_->Put('u');
os_->Put(hexDigits[(trail >> 12) & 15]);
os_->Put(hexDigits[(trail >> 8) & 15]);
os_->Put(hexDigits[(trail >> 4) & 15]);
os_->Put(hexDigits[(trail ) & 15]);
}
}
else if ((sizeof(Ch) == 1 || (unsigned)c < 256) && escape[(unsigned char)c]) {
is.Take();
os_->Put('\\');
os_->Put(escape[(unsigned char)c]);
if (escape[(unsigned char)c] == 'u') {
os_->Put('0');
os_->Put('0');
os_->Put(hexDigits[(unsigned char)c >> 4]);
os_->Put(hexDigits[(unsigned char)c & 0xF]);
}
}
else
if (!Transcoder<SourceEncoding, TargetEncoding>::Transcode(is, *os_))
return false;
}
os_->Put('\"');
return true;
}
bool WriteStartObject() { os_->Put('{'); return true; }
bool WriteEndObject() { os_->Put('}'); return true; }
bool WriteStartArray() { os_->Put('['); return true; }
bool WriteEndArray() { os_->Put(']'); return true; }
void Prefix(Type type) {
(void)type;
if (level_stack_.GetSize() != 0) { // this value is not at root
Level* level = level_stack_.template Top<Level>();
if (level->valueCount > 0) {
if (level->inArray)
os_->Put(','); // add comma if it is not the first element in array
else // in object
os_->Put((level->valueCount % 2 == 0) ? ',' : ':');
}
if (!level->inArray && level->valueCount % 2 == 0)
RAPIDJSON_ASSERT(type == kStringType); // if it's in object, then even number should be a name
level->valueCount++;
}
else {
RAPIDJSON_ASSERT(!hasRoot_); // Should only has one and only one root.
hasRoot_ = true;
}
}
OutputStream* os_;
internal::Stack<StackAllocator> level_stack_;
bool hasRoot_;
private:
// Prohibit copy constructor & assignment operator.
Writer(const Writer&);
Writer& operator=(const Writer&);
};
// Full specialization for StringStream to prevent memory copying
template<>
inline bool Writer<StringBuffer>::WriteInt(int i) {
char *buffer = os_->Push(11);
const char* end = internal::i32toa(i, buffer);
os_->Pop(11 - (end - buffer));
return true;
}
template<>
inline bool Writer<StringBuffer>::WriteUint(unsigned u) {
char *buffer = os_->Push(10);
const char* end = internal::u32toa(u, buffer);
os_->Pop(10 - (end - buffer));
return true;
}
template<>
inline bool Writer<StringBuffer>::WriteInt64(int64_t i64) {
char *buffer = os_->Push(21);
const char* end = internal::i64toa(i64, buffer);
os_->Pop(21 - (end - buffer));
return true;
}
template<>
inline bool Writer<StringBuffer>::WriteUint64(uint64_t u) {
char *buffer = os_->Push(20);
const char* end = internal::u64toa(u, buffer);
os_->Pop(20 - (end - buffer));
return true;
}
template<>
inline bool Writer<StringBuffer>::WriteDouble(double d) {
char *buffer = os_->Push(25);
char* end = internal::dtoa(d, buffer);
os_->Pop(25 - (end - buffer));
return true;
}
RAPIDJSON_NAMESPACE_END
#ifdef _MSC_VER
RAPIDJSON_DIAG_POP
#endif
#endif // RAPIDJSON_RAPIDJSON_H_
+203
Ver Arquivo
@@ -0,0 +1,203 @@
This file is a conversion from the ENGINE settings of 15.04 to the ENGINE setting of 2.0
This is NOT a conversion on the frontend internal setting names (15.04 has the dictionary of doom)
autoCenter ? ==> center_object OR machine_center_is_zero ??
coolHeadLift ==> cool_lift_head
downSkinCount ==> bottom_layers
enableCombing ==> retraction_combing
enableOozeShield ==> ooze_shield_enabled
endCode ==> machine_end_gcode
extruderOffset[MAX_EXTRUDERS] = (machine_nozzle_offset_x, machine_nozzle_offset_y)
extrusionWidth ==> infill_line_width, skirt_line_width, support_line_width
fanFullOnLayerNr ==> cool_fan_full_layer
fanSpeedMax ==> cool_fan_speed_max
fanSpeedMin ==> cool_fan_speed_min
filamentDiameter ==> material_diameter
filamentFlow ==> material_flow
fixHorrible ==> meshfix_union_all AND/OR meshfix_union_all_remove_holes AND/OR meshfix_extensive_stitching AND/OR magic_mesh_surface_mode
gcodeFlavor ==> machine_gcode_flavor
infillOverlap ==> infill_overlap
infillPattern ==> infill_pattern
infillSpeed ==> speed_infill
initialLayerSpeed ==> speed_layer_0
initialLayerThickness ==> layer_height_0
initialSpeedupLayers ==> speed_slowdown_layers
inset0Speed ==> speed_wall_0
insetCount ==> wall_line_count
insetXSpeed ==> speed_wall_x
layer0extrusionWidth [ Doesn't exist anymore ]
layerThickness ==> layer_height
matrix [ Doesn't exist anymore ]
minimalExtrusionBeforeRetraction
minimalFeedrate ==> cool_min_speed
minimalLayerTime ==> cool_min_layer_time
moveSpeed ==> speed_travel
multiVolumeOverlap ==> multiple_mesh_overlap
nozzleSize ==> machine_nozzle_size
objectPosition ==> mesh_position_x, mesh_position_y, mesh_position_z
objectSink [ Doesn't exist in CuraEngine anymore ]
perimeterBeforeInfill = not(infill_before_walls)
postSwitchExtruderCode ==> machine_extruder_start_code
preSwitchExtruderCode ==> machine_extruder_end_code
printSpeed ==> speed_prime_tower, speed_support_lines, speed_support_roof, skirt_speed
raftAirGap ==> raft_airgap
raftAirGapLayer0 ?!?!?
raftBaseLinewidth ==> raft_base_line_width
raftBaseSpeed ==> raft_interface_speed, raft_base_speed
raftBaseThickness ==> raft_base_thickness
raftFanSpeed ==> raft_base_fan_speed, raft_interface_fan_speed, raft_surface_fan_speed
raftInterfaceLineSpacing==> raft_interface_line_spacing
raftInterfaceLinewidth ==> raft_interface_line_width
raftInterfaceThickness ==> raft_interface_thickness
raftLineSpacing ==> raft_base_line_spacing
raftMargin ==> raft_margin
raftSurfaceLayers ==> raft_surface_layers
raftSurfaceLineSpacing ==> raft_surface_line_spacing
raftSurfaceLinewidth ==> raft_surface_line_width
raftSurfaceSpeed ==> raft_surface_speed
raftSurfaceThickness ==> raft_surface_thickness
retractionAmount ==> retraction_amount (set retraction_enable = true)
retractionAmountExtruderSwitch ==> switch_extruder_retraction_amount
retractionAmountPrime ==> retraction_extra_prime_amount
retractionMinimalDistance ==> retraction_extrusion_window ( set retraction_count_max = 1 )
retractionSpeed ==> retraction_retract_speed (, retraction_prime_speed ?), switch_extruder_retraction_speed
retractionZHop ==> retraction_hop
simpleMode ??!
skinSpeed ==> speed_topbottom
skirtDistance ==> skirt_gap
skirtLineCount ==> brim_line_count, skirt_line_count
skirtMinLength ==> skirt_minimal_length
sparseInfillLineDistance ==> infill_line_distance
spiralizeMode ==> magic_spiralize
startCode ==> machine_start_gcode
supportAngle ==> support_angle, support_enable=true if support_angle>0
supportEverywhere ==> support_type
supportExtruder ==> support_extruder_nr, support_extruder_nr_layer_0
supportLineDistance ==> support_line_distance
supportType ==> support_pattern
supportXYDistance ==> support_xy_distance
supportZDistance ==> support_z_distance
upSkinCount ==> top_layers
wipeTowerSize ==> prime_tower_size
NEW:
adhesion_extruder_nr
adhesion_type
alternate_extra_perimeter
coasting_enable
coasting_min_volume_move
coasting_min_volume_retract
coasting_speed_move
coasting_speed_retract
coasting_volume_move
coasting_volume_retract
cool_min_layer_time_fan_speed_max
draft_shield_dist
draft_shield_height
extruder_nr
fill_perimeter_gaps
infill_sparse_thickness
infill_wipe_dist
machine_depth
machine_extruder_count
machine_extruder_end_pos_abs
machine_extruder_end_pos_x
machine_extruder_end_pos_y
machine_extruder_start_pos_abs
machine_extruder_start_pos_x
machine_extruder_start_pos_y
machine_heated_bed
machine_nozzle_cool_down_speed
machine_nozzle_expansion_angle
machine_nozzle_head_distance
machine_nozzle_heat_up_speed
machine_nozzle_tip_outer_diameter
machine_print_temp_wait
machine_use_extruder_offset_to_offset_coords
machine_width
magic_fuzzy_skin_enabled
magic_fuzzy_skin_point_dist
magic_fuzzy_skin_thickness
material_bed_temperature
material_bed_temp_prepend
material_bed_temp_wait
material_extrusion_cool_down_speed
material_flow_dependent_temperature
material_flow_temp_graph
material_print_temperature
material_print_temp_prepend
material_print_temp_wait
material_standby_temperature
meshfix_keep_open_polygons
ooze_shield_angle
ooze_shield_dist
prime_tower_dir_outward
prime_tower_distance
prime_tower_flow
prime_tower_line_width
prime_tower_position_x
prime_tower_position_y
prime_tower_wipe_enabled
remove_overlapping_walls_0_enabled
remove_overlapping_walls_x_enabled
retraction_min_travel
skin_alternate_rotation
skin_line_width
skin_no_small_gaps_heuristic
skin_outline_count
support_area_smoothing
support_bottom_distance
support_bottom_stair_step_height
support_conical_angle
support_conical_enabled
support_conical_min_width
support_connect_zigzags
support_join_distance
support_minimal_diameter
support_offset
support_roof_enable
support_roof_extruder_nr
support_roof_height
support_roof_line_distance
support_roof_line_width
support_roof_pattern
support_top_distance
support_tower_diameter
support_tower_roof_angle
switch_extruder_prime_speed
top_bottom_pattern
travel_avoid_distance
travel_avoid_other_parts
travel_compensate_overlapping_walls_enabled
wall_line_width_0
wall_line_width_x
wireframe_bottom_delay
wireframe_drag_along
wireframe_enabled
wireframe_fall_down
wireframe_flat_delay
wireframe_flow_connection
wireframe_flow_flat
wireframe_height
wireframe_nozzle_clearance
wireframe_printspeed_bottom
wireframe_printspeed_down
wireframe_printspeed_flat
wireframe_printspeed_up
wireframe_roof_drag_along
wireframe_roof_fall_down
wireframe_roof_inset
wireframe_roof_outer_delay
wireframe_straight_before_down
wireframe_strategy
wireframe_top_delay
wireframe_top_jump
wireframe_up_half_speed
xy_offset
z_seam_type
+19
Ver Arquivo
@@ -0,0 +1,19 @@
find engine setting literals
cd ~/Development/CuraEngine/output/reflection/
~/bin/substitute.pl y 'while(/getSetting\w+\("(\w+)"\)/gsm) { print "$1\n"; }' ../../src/ | sort | uniq > engineSettingLiterals.txt
run setting inheritance reflection
cd ~/Development/CuraEngine
./build/CuraEngine analyse ../Cura/resources/definitions/fdmprinter.def.json meta/refl_ff.gv output/reflection/engineSettingLiterals.txt -piew
dot meta/refl_ff.gv -Tpng > meta/rafl_ff_dotted.png
green block = used in engine
red edge = inherit function only
black edge = parent-child relation
+130
Ver Arquivo
@@ -0,0 +1,130 @@
[ problem ]
gantry_height introduced by Jaime while there already was machine_nozzle_gantry_distance
[ RENAMES ]
raft_base_linewidth > raft_base_line_width
raft_interface_linewidth > raft_interface_line_width
fill_overlap > infill_overlap
fill_pattern > infill_pattern
fill_sparse_combine > infill_sparse_combine
fill_sparse_density > infill_sparse_density
fill_sparse_thickness > infill_sparse_thickness
support_fill_rate > support_infill_rate
[ SPLITS ]
raft_line_spacing > raft_base_line_spacing (, raft_interface_line_spacing, raft_surface_line_spacing)
wall_overlap_avoid_enabled > remove_overlapping_walls_enabled (, remove_overlapping_walls_0_enabled, remove_overlapping_walls_x_enabled)
retraction_minimal_extrusion > retraction_extrusion_window (+ retraction_count_max = 1)
magic_mesh_surface_mode : false >> "Normal"
magic_mesh_surface_mode : true >> "Surface"
[ NEW ]
alternate_extra_perimeter
coasting_enable
coasting_min_volume
coasting_min_volume_move
coasting_min_volume_retract
coasting_speed
coasting_speed_move
coasting_speed_retract
coasting_volume
coasting_volume_move
coasting_volume_retract
fill_perimeter_gaps
draft_shield_dist
draft_shield_enabled
draft_shield_height
draft_shield_height_limitation
infill_wipe_dist
line_width (was wall_line_width)
machine_extruder_count
machine_head_polygon
machine_head_with_fans_polygon
machine_heat_zone_length
magic_mesh_surface_mode
meshfix_extensive_stitching
meshfix_keep_open_polygons
meshfix_union_all
meshfix_union_all_remove_holes
print_sequence
raft_base_line_spacing (from raft_line_spacing)
raft_base_line_width
raft_fan_speed
raft_interface_fan_speed
raft_interface_line_spacing
raft_interface_speed
raft_speed
raft_surface_fan_speed
raft_surface_line_spacing
raft_surface_line_width
raft_surface_speed
raft_surface_thickness
remove_overlapping_walls_0_enabled
remove_overlapping_walls_enabled
remove_overlapping_walls_x_enabled
retraction_count_max
retraction_extrusion_window (from retraction_minimal_extrusion)
retraction_extra_prime_amount
skin_alternate_rotation
speed_support_lines
speed_support_roof
support_conical_angle
support_conical_enabled
support_conical_min_width
support_offset
support_roof_enable
support_roof_height
support_roof_line_width
travel_avoid_distance
travel_avoid_other_parts
travel_compensate_overlapping_walls_enabled
z_seam_type
[ DUAL EXTRUSION ]
extruder_nr
machine_use_extruder_offset_to_offset_coords
machine_nozzle_offset_x
machine_nozzle_offset_y
machine_extruder_start_code
machine_extruder_start_pos_abs
machine_extruder_start_pos_x
machine_extruder_start_pos_y
machine_extruder_end_pos_abs
machine_extruder_end_pos_x
machine_extruder_end_pos_y
machine_extruder_end_code
prime_tower_enable
prime_tower_size
prime_tower_position_x
prime_tower_position_y
prime_tower_flow
prime_tower_wipe_enabled
ooze_shield_enabled
ooze_shield_angle
ooze_shield_dist
Arquivo binário não exibido.

Depois

Largura:  |  Altura:  |  Tamanho: 284 KiB

+35
Ver Arquivo
@@ -0,0 +1,35 @@
/** Copyright (C) 2016 Tim Kuipers - Released under terms of the AGPLv3 License */
#include "ConicalOverhang.h"
namespace cura {
void ConicalOverhang::apply(Slicer* slicer, double angle, int layer_thickness)
{
double tanAngle = tan(angle); // the XY-component of the angle
int max_dist_from_lower_layer = tanAngle * layer_thickness; // max dist which can be bridged
for (unsigned int layer_nr = slicer->layers.size() - 2; static_cast<int>(layer_nr) >= 0; layer_nr--)
{
SlicerLayer& layer = slicer->layers[layer_nr];
SlicerLayer& layer_above = slicer->layers[layer_nr + 1];
if (std::abs(max_dist_from_lower_layer) < 5)
{ // magically nothing happens when max_dist_from_lower_layer == 0
// below magic code solves that
int safe_dist = 20;
Polygons diff = layer_above.polygons.difference(layer.polygons.offset(-safe_dist));
layer.polygons = layer.polygons.unionPolygons(diff);
layer.polygons = layer.polygons.smooth(safe_dist);
layer.polygons.simplify(safe_dist, safe_dist * safe_dist / 4);
// somehow layer.polygons get really jagged lines with a lot of vertices
// without the above steps slicing goes really slow
}
else
{
layer.polygons = layer.polygons.unionPolygons(layer_above.polygons.offset(-max_dist_from_lower_layer));
}
}
}
}//namespace cura
+30
Ver Arquivo
@@ -0,0 +1,30 @@
/** Copyright (C) 2016 Tim Kuipers - Released under terms of the AGPLv3 License */
#ifndef CONICAL_OVERHANG_H
#define CONICAL_OVERHANG_H
#include "slicer.h"
namespace cura {
/*!
* A class for changing the geometry of a model such that it is printable without support -
* Or at least with at least support as possible
*/
class ConicalOverhang
{
public:
/*!
* Change the slice data such that the model becomes more printable
*
* \param[in,out] slicer The slice data
* \param angle The maximum angle which can be printed without generating support (or at least generating least support)
* \param layer_thickness The general layer thickness
*/
static void apply(Slicer* slicer, double angle, int layer_thickness);
};
}//namespace cura
#endif // CONICAL_OVERHANG_H
+27
Ver Arquivo
@@ -0,0 +1,27 @@
/** Copyright (C) 2016 Ultimaker - Released under terms of the AGPLv3 License */
#include "ExtruderTrain.h"
namespace cura
{
int ExtruderTrain::getExtruderNr()
{
return extruder_nr;
}
ExtruderTrain::ExtruderTrain(SettingsBaseVirtual* settings, int extruder_nr)
: SettingsBase(settings)
, extruder_nr(extruder_nr)
{
}
bool ExtruderTrain::getIsUsed() const
{
return is_used;
}
void ExtruderTrain::setIsUsed(bool used)
{
is_used = used;
}
}//namespace cura
+25
Ver Arquivo
@@ -0,0 +1,25 @@
/** Copyright (C) 2016 Ultimaker - Released under terms of the AGPLv3 License */
#ifndef EXTRUDER_TRAIN_H
#define EXTRUDER_TRAIN_H
#include "settings/settings.h"
namespace cura
{
class ExtruderTrain : public SettingsBase
{
int extruder_nr;
bool is_used = false; //!< whether this extruder train is (probably) used during printing the current meshgroup
public:
int getExtruderNr();
bool getIsUsed() const; //!< return whether this extruder train is (probably) used during printing the current meshgroup
void setIsUsed(bool used); //!< set whether this extruder train is (probably) used during printing the current meshgroup
ExtruderTrain(SettingsBaseVirtual* settings, int extruder_nr);
};
}//namespace cura
#endif // EXTRUDER_TRAIN_H
+23
Ver Arquivo
@@ -0,0 +1,23 @@
#ifndef FAN_SPEED_LAYER_TIME_H
#define FAN_SPEED_LAYER_TIME_H
#include "settings/settings.h"
namespace cura
{
struct FanSpeedLayerTimeSettings
{
public:
double cool_min_layer_time;
double cool_min_layer_time_fan_speed_max;
double cool_fan_speed_0;
double cool_fan_speed_min;
double cool_fan_speed_max;
double cool_min_speed;
int cool_fan_full_layer;
};
} // namespace cura
#endif // FAN_SPEED_LAYER_TIME_H
Diferenças do arquivo suprimidas por serem muito extensas Carregar Diff
+401
Ver Arquivo
@@ -0,0 +1,401 @@
#ifndef GCODE_WRITER_H
#define GCODE_WRITER_H
#include <fstream>
#include "utils/gettime.h"
#include "utils/logoutput.h"
#include "utils/NoCopy.h"
#include "utils/polygonUtils.h"
#include "sliceDataStorage.h"
#include "raft.h"
#include "infill.h"
#include "bridge.h"
#include "pathOrderOptimizer.h"
#include "gcodePlanner.h"
#include "gcodeExport.h"
#include "commandSocket.h"
#include "PrimeTower.h"
#include "FanSpeedLayerTime.h"
#include "PrintFeature.h"
#include "LayerPlanBuffer.h"
namespace cura
{
/*!
* Secondary stage in Fused Filament Fabrication processing: The generated polygons are used in the gcode generation.
* Some polygons in the SliceDataStorage signify areas which are to be filled with parallel lines,
* while other polygons signify the contours which should be printed.
*
* The main function of this class is FffGcodeWriter::writeGCode().
*/
class FffGcodeWriter : public SettingsMessenger, NoCopy
{
friend class FffProcessor; // cause WireFrame2Gcode uses the member [gcode] (TODO)
private:
int max_object_height; //!< The maximal height of all previously sliced meshgroups, used to avoid collision when moving to the next meshgroup to print.
/*
* Buffer for all layer plans (of type GCodePlanner)
*
* The layer plans are buffered so that we can start heating up a nozzle several layers before it needs to be used.
* Another reason is to perform Auto Temperature.
*/
LayerPlanBuffer layer_plan_buffer;
/*!
* The class holding the current state of the gcode being written.
*
* It holds information such as the last written position etc.
*/
GCodeExport gcode;
/*!
* The gcode file to write to when using CuraEngine as command line tool.
*/
std::ofstream output_file;
/*!
* Whether the skirt or brim polygons have been processed into planned paths
* for each extruder train.
*/
bool skirt_brim_is_processed[MAX_EXTRUDERS];
std::vector<FanSpeedLayerTimeSettings> fan_speed_layer_time_settings_per_extruder; //!< The settings used relating to minimal layer time and fan speeds. Configured for each extruder.
Point last_position_planned; //!< The position of the head before planning the next layer
int current_extruder_planned; //!< The extruder train in use before planning the next layer
public:
FffGcodeWriter(SettingsBase* settings_)
: SettingsMessenger(settings_)
, layer_plan_buffer(this, gcode)
, last_position_planned(no_point)
, current_extruder_planned(0) // changed somewhere early in FffGcodeWriter::writeGCode
{
max_object_height = 0;
}
/*!
* Set the target to write gcode to: to a file.
*
* Used when CuraEngine is used as command line tool.
*
* \param filename The filename of the file to which to write the gcode.
*/
bool setTargetFile(const char* filename)
{
output_file.open(filename);
if (output_file.is_open())
{
gcode.setOutputStream(&output_file);
return true;
}
return false;
}
/*!
* Set the target to write gcode to: an output stream.
*
* Used when CuraEngine is NOT used as command line tool.
*
* \param stream The stream to write gcode to.
*/
void setTargetStream(std::ostream* stream)
{
gcode.setOutputStream(stream);
}
/*!
* Get the total extruded volume for a specific extruder in mm^3
*
* Retractions and unretractions don't contribute to this.
*
* \param extruder_nr The extruder number for which to get the total netto extruded volume
* \return total filament printed in mm^3
*/
double getTotalFilamentUsed(int extruder_nr)
{
return gcode.getTotalFilamentUsed(extruder_nr);
}
/*!
* Get the total estimated print time in seconds
*
* \return total print time in seconds
*/
double getTotalPrintTime()
{
return gcode.getTotalPrintTime();
}
/*!
* Write all the gcode for the current meshgroup.
* This is the primary function of this class.
*
* \param[in] storage The data storage from which to get the polygons to print and the areas to fill.
* \param timeKeeper The stop watch to see how long it takes for each of the stages in the slicing process.
*/
void writeGCode(SliceDataStorage& storage, TimeKeeper& timeKeeper);
private:
/*!
* Set the FffGcodeWriter::fan_speed_layer_time_settings by retrieving all settings from the global/per-meshgroup settings.
*
* \param[out] storage The data storage to which to save the configuration
*/
void setConfigFanSpeedLayerTime(SliceDataStorage& storage);
/*!
* Create and set the SliceDataStorage::coasting_config for each extruder.
*
* \param[out] storage The data storage to which to save the configuration
*/
void setConfigCoasting(SliceDataStorage& storage);
/*!
* Set the retraction config globally, per extruder and per mesh.
*
* \param[out] storage The data storage to which to save the configurations
*/
void setConfigRetraction(SliceDataStorage& storage);
/*!
* Initialize the GcodePathConfig config parameters which don't change over
* all layers, for each feature.
*
* The features are: skirt or brim, support and for each mesh: outer wall,
* inner walls, skin, infill (and combined infill).
*
* \param[out] storage The data storage to which to save the configurations.
*/
void initConfigs(SliceDataStorage& storage);
/*!
* Set temperatures and perform initial priming.
*
* Write a stub header if CuraEngine is in command line tool mode. (Cause writing the header afterwards would entail moving all gcode down.)
*
* \param[in] storage where the slice data is stored.
*/
void processStartingCode(SliceDataStorage& storage);
/*!
* Move up and over the already printed meshgroups to print the next meshgroup.
*
* \param[in] storage where the slice data is stored.
*/
void processNextMeshGroupCode(SliceDataStorage& storage);
/*!
* Add raft layer plans onto the FffGcodeWriter::layer_plan_buffer
*
* \param[in,out] storage where the slice data is stored.
* \param total_layers The total number of layers.
*/
void processRaft(SliceDataStorage& storage, unsigned int total_layers);
/*!
* Convert the polygon data of a layer into a layer plan on the FffGcodeWriter::layer_plan_buffer
*
* In case of negative layer numbers, create layers only containing the data from
* the helper parts (support etc) to fill up the gap between the raft and the model.
*
* \param[in] storage where the slice data is stored.
* \param layer_nr The index of the layer to write the gcode of.
* \param total_layers The total number of layers.
*/
void processLayer(SliceDataStorage& storage, int layer_nr, unsigned int total_layers);
/*!
* Plan priming of all used extruders which haven't been primed yet
* \param[in] storage where the slice data is stored.
* \param layer_plan The initial planning of the g-code of the layer.
* \param layer_nr The index of the layer to write the gcode of.
*/
void ensureAllExtrudersArePrimed(SliceDataStorage& storage, GCodePlanner& layer_plan, const int layer_nr);
/*!
* Add the skirt or the brim to the layer plan \p gcodeLayer.
*
* \param Storage where the slice data is stored.
* \param gcodeLayer The initial planning of the g-code of the layer.
* \param extruder_nr The extruder train for which to process the skirt or
* brim.
*/
void processSkirtBrim(SliceDataStorage& storage, GCodePlanner& gcodeLayer, unsigned int extruder_nr);
/*!
* Adds the ooze shield to the layer plan \p gcodeLayer.
*
* \param[in] storage where the slice data is stored.
* \param gcodeLayer The initial planning of the gcode of the layer.
* \param layer_nr The index of the layer to write the gcode of.
*/
void processOozeShield(SliceDataStorage& storage, GCodePlanner& gcodeLayer, unsigned int layer_nr);
/*!
* Adds the draft protection screen to the layer plan \p gcodeLayer.
*
* \param[in] storage where the slice data is stored.
* \param gcodeLayer The initial planning of the gcode of the layer.
* \param layer_nr The index of the layer to write the gcode of.
*/
void processDraftShield(SliceDataStorage& storage, GCodePlanner& gcodeLayer, unsigned int layer_nr);
/*!
* Calculate in which order to plan the extruders
*
* \param[in] storage where the slice data is stored.
* \param current_extruder The current extruder with which we last printed
* \return A vector of pairs of extruder numbers coupled with the mesh indices ordered on print order for that extruder.
*/
std::vector<int> calculateExtruderOrder(SliceDataStorage& storage, int current_extruder);
/*!
* Calculate in which order to plan the meshes of a specific extruder
*
* \param[in] storage where the slice data is stored.
* \param extruder_nr The extruder for which to determine the order
* \return A vector of pairs of extruder numbers coupled with the mesh indices ordered on print order for that extruder.
*/
std::vector<unsigned int> calculateMeshOrder(SliceDataStorage& storage, int extruder_nr);
/*!
* Add a single layer from a single mesh-volume to the layer plan \p gcodeLayer in mesh surface mode.
*
* \param[in] storage where the slice data is stored.
* \param mesh The mesh to add to the layer plan \p gcodeLayer.
* \param gcodeLayer The initial planning of the gcode of the layer.
* \param layer_nr The index of the layer to write the gcode of.
*
*/
void addMeshLayerToGCode_meshSurfaceMode(SliceDataStorage& storage, SliceMeshStorage* mesh, GCodePlanner& gcodeLayer, int layer_nr);
/*!
* Add the open polylines from a single layer from a single mesh-volume to the layer plan \p gcodeLayer for mesh the surface modes.
*
* \param[in] storage where the slice data is stored.
* \param mesh The mesh for which to add to the layer plan \p gcodeLayer.
* \param gcodeLayer The initial planning of the gcode of the layer.
* \param layer_nr The index of the layer to write the gcode of.
*
*/
void addMeshOpenPolyLinesToGCode(SliceDataStorage& storage, SliceMeshStorage* mesh, GCodePlanner& gcode_layer, int layer_nr);
/*!
* Add a single layer from a single mesh-volume to the layer plan \p gcodeLayer.
*
* \param[in] storage where the slice data is stored.
* \param mesh The mesh to add to the layer plan \p gcodeLayer.
* \param gcodeLayer The initial planning of the gcode of the layer.
* \param layer_nr The index of the layer to write the gcode of.
*
*/
void addMeshLayerToGCode(SliceDataStorage& storage, SliceMeshStorage* mesh, GCodePlanner& gcodeLayer, int layer_nr);
/*!
* Add thicker (multiple layers) sparse infill for a given part in a layer plan.
*
* \param gcodeLayer The initial planning of the gcode of the layer.
* \param mesh The mesh for which to add to the layer plan \p gcodeLayer.
* \param part The part for which to create gcode
* \param layer_nr The current layer number.
* \param infill_line_distance The distance between the infill lines
* \param infill_overlap The distance by which the infill overlaps with the wall insets.
* \param fillAngle The angle in the XY plane at which the infill is generated.
*/
void processMultiLayerInfill(GCodePlanner& gcodeLayer, SliceMeshStorage* mesh, SliceLayerPart& part, unsigned int layer_nr, int infill_line_distance, int infill_overlap, int fillAngle);
/*!
* Add normal sparse infill for a given part in a layer.
* \param gcodeLayer The initial planning of the gcode of the layer.
* \param mesh The mesh for which to add to the layer plan \p gcodeLayer.
* \param part The part for which to create gcode
* \param layer_nr The current layer number.
* \param infill_line_distance The distance between the infill lines
* \param infill_overlap The distance by which the infill overlaps with the wall insets.
* \param fillAngle The angle in the XY plane at which the infill is generated.
*/
void processSingleLayerInfill(GCodePlanner& gcodeLayer, SliceMeshStorage* mesh, SliceLayerPart& part, unsigned int layer_nr, int infill_line_distance, int infill_overlap, int fillAngle);
/*!
* Generate the insets for the walls of a given layer part.
* \param gcodeLayer The initial planning of the gcode of the layer.
* \param mesh The mesh for which to add to the layer plan \p gcodeLayer.
* \param part The part for which to create gcode
* \param layer_nr The current layer number.
* \param z_seam_type dir3ective for where to start the outer paerimeter of a part
*/
void processInsets(GCodePlanner& gcodeLayer, SliceMeshStorage* mesh, SliceLayerPart& part, unsigned int layer_nr, EZSeamType z_seam_type);
/*!
* Add the gcode of the top/bottom skin of the given part.
* \param gcodeLayer The initial planning of the gcode of the layer.
* \param mesh The mesh for which to add to the layer plan \p gcodeLayer.
* \param part The part for which to create gcode
* \param layer_nr The current layer number.
* \param skin_overlap The distance by which the skin overlaps with the wall insets.
* \param fillAngle The angle in the XY plane at which the infill is generated.
*/
void processSkin(cura::GCodePlanner& gcode_layer, cura::SliceMeshStorage* mesh, cura::SliceLayerPart& part, unsigned int layer_nr, int skin_overlap, int infill_angle);
/*!
* Add the support to the layer plan \p gcodeLayer of the current layer for all support parts with the given \p extruder_nr.
* \param[in] storage where the slice data is stored.
* \param gcodeLayer The initial planning of the gcode of the layer.
* \param layer_nr The index of the layer to write the gcode of.
* \return whether any support was added to the layer plan
*/
bool addSupportToGCode(SliceDataStorage& storage, GCodePlanner& gcodeLayer, int layer_nr, int extruder_nr);
/*!
* Add the support lines/walls to the layer plan \p gcodeLayer of the current layer.
* \param[in] storage where the slice data is stored.
* \param gcodeLayer The initial planning of the gcode of the layer.
* \param layer_nr The index of the layer to write the gcode of.
* \return whether any support infill was added to the layer plan
*/
bool addSupportInfillToGCode(SliceDataStorage& storage, GCodePlanner& gcodeLayer, int layer_nr);
/*!
* Add the support skins to the layer plan \p gcodeLayer of the current layer.
* \param[in] storage where the slice data is stored.
* \param gcodeLayer The initial planning of the gcode of the layer.
* \param layer_nr The index of the layer to write the gcode of.
* \return whether any support skin was added to the layer plan
*/
bool addSupportRoofsToGCode(SliceDataStorage& storage, GCodePlanner& gcodeLayer, int layer_nr);
/*!
* Change to a new extruder, and add the prime tower instructions if the new extruder is different from the last.
*
* On layer 0 this function adds the skirt for the nozzle it switches to, instead of the prime tower.
*
* \param[in] storage where the slice data is stored.
* \param gcodeLayer The initial planning of the gcode of the layer.
* \param layer_nr The index of the layer to write the gcode of.
* \param extruder_nr The extruder to which to switch
*/
void setExtruder_addPrime(SliceDataStorage& storage, GCodePlanner& gcode_layer, int layer_nr, int extruder_nr);
/*!
* Add the prime tower gcode for the current layer.
* \param[in] storage where the slice data is stored.
* \param gcodeLayer The initial planning of the gcode of the layer.
* \param layer_nr The index of the layer to write the gcode of.
* \param prev_extruder The current extruder with which we last printed.
*/
void addPrimeTower(SliceDataStorage& storage, GCodePlanner& gcodeLayer, int layer_nr, int prev_extruder);
/*!
* Add the end gcode and set all temperatures to zero.
*/
void finalize();
};
}//namespace cura
#endif // GCODE_WRITER_H
+764
Ver Arquivo
@@ -0,0 +1,764 @@
#include "FffPolygonGenerator.h"
#include <algorithm>
#include <map> // multimap (ordered map allowing duplicate keys)
#include "utils/math.h"
#include "utils/algorithm.h"
#include "slicer.h"
#include "utils/gettime.h"
#include "utils/logoutput.h"
#include "MeshGroup.h"
#include "support.h"
#include "multiVolumes.h"
#include "layerPart.h"
#include "WallsComputation.h"
#include "SkirtBrim.h"
#include "skin.h"
#include "infill.h"
#include "raft.h"
#include "progress/Progress.h"
#include "PrintFeature.h"
#include "ConicalOverhang.h"
#include "progress/ProgressEstimator.h"
#include "progress/ProgressStageEstimator.h"
#include "progress/ProgressEstimatorLinear.h"
namespace cura
{
bool FffPolygonGenerator::generateAreas(SliceDataStorage& storage, MeshGroup* meshgroup, TimeKeeper& timeKeeper)
{
if (!sliceModel(meshgroup, timeKeeper, storage))
{
return false;
}
slices2polygons(storage, timeKeeper);
return true;
}
unsigned int FffPolygonGenerator::getDraftShieldLayerCount(const unsigned int total_layers) const
{
if (!getSettingBoolean("draft_shield_enabled"))
{
return 0;
}
switch (getSettingAsDraftShieldHeightLimitation("draft_shield_height_limitation"))
{
default:
case DraftShieldHeightLimitation::FULL:
return total_layers;
case DraftShieldHeightLimitation::LIMITED:
return std::max(0, (getSettingInMicrons("draft_shield_height") - getSettingInMicrons("layer_height_0")) / getSettingInMicrons("layer_height") + 1);
}
}
bool FffPolygonGenerator::sliceModel(MeshGroup* meshgroup, TimeKeeper& timeKeeper, SliceDataStorage& storage) /// slices the model
{
Progress::messageProgressStage(Progress::Stage::SLICING, &timeKeeper);
storage.model_min = meshgroup->min();
storage.model_max = meshgroup->max();
storage.model_size = storage.model_max - storage.model_min;
log("Slicing model...\n");
int initial_layer_thickness = getSettingInMicrons("layer_height_0");
if(initial_layer_thickness <= 0) //Initial layer height of 0 is not allowed. Negative layer height is nonsense.
{
logError("Initial layer height %i is disallowed.\n", initial_layer_thickness);
return false;
}
int layer_thickness = getSettingInMicrons("layer_height");
if(layer_thickness <= 0) //Layer height of 0 is not allowed. Negative layer height is nonsense.
{
logError("Layer height %i is disallowed.\n", layer_thickness);
return false;
}
int initial_slice_z = initial_layer_thickness - layer_thickness / 2;
int slice_layer_count = (storage.model_max.z - initial_slice_z) / layer_thickness + 1;
if (slice_layer_count <= 0) //Model is shallower than layer_height_0, so not even the first layer is sliced. Return an empty model then.
{
return true; //This is NOT an error state!
}
std::vector<Slicer*> slicerList;
for(unsigned int mesh_idx = 0; mesh_idx < meshgroup->meshes.size(); mesh_idx++)
{
Mesh& mesh = meshgroup->meshes[mesh_idx];
Slicer* slicer = new Slicer(&mesh, initial_slice_z, layer_thickness, slice_layer_count, mesh.getSettingBoolean("meshfix_keep_open_polygons"), mesh.getSettingBoolean("meshfix_extensive_stitching"));
slicerList.push_back(slicer);
/*
for(SlicerLayer& layer : slicer->layers)
{
//Reporting the outline here slows down the engine quite a bit, so only do so when debugging.
sendPolygons("outline", layer_nr, layer.z, layer.polygonList);
sendPolygons("openoutline", layer_nr, layer.openPolygonList);
}
*/
Progress::messageProgress(Progress::Stage::SLICING, mesh_idx + 1, meshgroup->meshes.size());
}
meshgroup->clear();///Clear the mesh face and vertex data, it is no longer needed after this point, and it saves a lot of memory.
for(unsigned int meshIdx=0; meshIdx < slicerList.size(); meshIdx++)
{
Mesh& mesh = storage.meshgroup->meshes[meshIdx];
if (mesh.getSettingBoolean("conical_overhang_enabled") && !mesh.getSettingBoolean("anti_overhang_mesh"))
{
ConicalOverhang::apply(slicerList[meshIdx], mesh.getSettingInAngleRadians("conical_overhang_angle"), layer_thickness);
}
}
Progress::messageProgressStage(Progress::Stage::PARTS, &timeKeeper);
if (storage.getSettingBoolean("carve_multiple_volumes"))
{
carveMultipleVolumes(slicerList, storage.getSettingBoolean("alternate_carve_order"));
}
generateMultipleVolumesOverlap(slicerList);
storage.print_layer_count = 0;
for (unsigned int meshIdx = 0; meshIdx < slicerList.size(); meshIdx++)
{
Mesh& mesh = storage.meshgroup->meshes[meshIdx];
Slicer* slicer = slicerList[meshIdx];
if (!mesh.getSettingBoolean("anti_overhang_mesh") && !mesh.getSettingBoolean("infill_mesh"))
{
storage.print_layer_count = std::max(storage.print_layer_count, (unsigned int)slicer->layers.size());
}
}
storage.support.supportLayers.resize(storage.print_layer_count);
storage.meshes.reserve(slicerList.size()); // causes there to be no resize in meshes so that the pointers in sliceMeshStorage._config to retraction_config don't get invalidated.
for (unsigned int meshIdx = 0; meshIdx < slicerList.size(); meshIdx++)
{
Slicer* slicer = slicerList[meshIdx];
Mesh& mesh = storage.meshgroup->meshes[meshIdx];
// always make a new SliceMeshStorage, so that they have the same ordering / indexing as meshgroup.meshes
storage.meshes.emplace_back(&meshgroup->meshes[meshIdx], slicer->layers.size()); // new mesh in storage had settings from the Mesh
SliceMeshStorage& meshStorage = storage.meshes.back();
if (mesh.getSettingBoolean("anti_overhang_mesh"))
{
for (unsigned int layer_nr = 0; layer_nr < slicer->layers.size(); layer_nr++)
{
SupportLayer& support_layer = storage.support.supportLayers[layer_nr];
SlicerLayer& slicer_layer = slicer->layers[layer_nr];
support_layer.anti_overhang = support_layer.anti_overhang.unionPolygons(slicer_layer.polygons);
}
continue;
}
if (mesh.getSettingBoolean("support_mesh"))
{
for (unsigned int layer_nr = 0; layer_nr < slicer->layers.size(); layer_nr++)
{
SupportLayer& support_layer = storage.support.supportLayers[layer_nr];
SlicerLayer& slicer_layer = slicer->layers[layer_nr];
support_layer.support_mesh.add(slicer_layer.polygons);
}
continue;
}
createLayerParts(meshStorage, slicer, mesh.getSettingBoolean("meshfix_union_all"), mesh.getSettingBoolean("meshfix_union_all_remove_holes"));
delete slicerList[meshIdx];
bool has_raft = getSettingAsPlatformAdhesion("adhesion_type") == EPlatformAdhesion::RAFT;
//Add the raft offset to each layer.
for(unsigned int layer_nr=0; layer_nr<meshStorage.layers.size(); layer_nr++)
{
SliceLayer& layer = meshStorage.layers[layer_nr];
meshStorage.layers[layer_nr].printZ +=
getSettingInMicrons("layer_height_0")
- initial_slice_z;
if (has_raft)
{
ExtruderTrain* train = storage.meshgroup->getExtruderTrain(getSettingAsIndex("adhesion_extruder_nr"));
layer.printZ +=
Raft::getTotalThickness(storage)
+ train->getSettingInMicrons("raft_airgap")
- train->getSettingInMicrons("layer_0_z_overlap"); // shift all layers (except 0) down
if (layer_nr == 0)
{
layer.printZ += train->getSettingInMicrons("layer_0_z_overlap"); // undo shifting down of first layer
}
}
if (layer.parts.size() > 0 || (mesh.getSettingAsSurfaceMode("magic_mesh_surface_mode") != ESurfaceMode::NORMAL && layer.openPolyLines.size() > 0) )
{
meshStorage.layer_nr_max_filled_layer = layer_nr; // last set by the highest non-empty layer
}
}
Progress::messageProgress(Progress::Stage::PARTS, meshIdx + 1, slicerList.size());
}
return true;
}
void FffPolygonGenerator::slices2polygons(SliceDataStorage& storage, TimeKeeper& time_keeper)
{
// compute layer count and remove first empty layers
// there is no separate progress stage for removeEmptyFisrtLayer (TODO)
unsigned int slice_layer_count = 0;
for (SliceMeshStorage& mesh : storage.meshes)
{
if (!mesh.getSettingBoolean("infill_mesh") && !mesh.getSettingBoolean("anti_overhang_mesh"))
{
slice_layer_count = std::max<unsigned int>(slice_layer_count, mesh.layers.size());
}
}
// handle meshes
std::vector<double> mesh_timings;
for (unsigned int mesh_idx = 0; mesh_idx < storage.meshes.size(); mesh_idx++)
{
mesh_timings.push_back(1.0); // TODO: have a more accurate estimate of the relative time it takes per mesh, based on the height and number of polygons
}
ProgressStageEstimator inset_skin_progress_estimate(mesh_timings);
Progress::messageProgressStage(Progress::Stage::INSET_SKIN, &time_keeper);
std::vector<unsigned int> mesh_order;
{ // compute mesh order
std::multimap<int, unsigned int> order_to_mesh_indices;
for (unsigned int mesh_idx = 0; mesh_idx < storage.meshes.size(); mesh_idx++)
{
order_to_mesh_indices.emplace(storage.meshes[mesh_idx].getSettingAsIndex("infill_mesh_order"), mesh_idx);
}
for (std::pair<const int, unsigned int>& order_and_mesh_idx : order_to_mesh_indices)
{
mesh_order.push_back(order_and_mesh_idx.second);
}
}
for (unsigned int mesh_order_idx(0); mesh_order_idx < mesh_order.size(); ++mesh_order_idx)
{
processBasicWallsSkinInfill(storage, mesh_order_idx, mesh_order, inset_skin_progress_estimate);
Progress::messageProgress(Progress::Stage::INSET_SKIN, mesh_order_idx + 1, storage.meshes.size());
}
for (unsigned int layer_nr = 0; layer_nr < slice_layer_count; layer_nr++)
{
SliceLayer* layer = nullptr;
for (unsigned int mesh_idx = 0; mesh_idx < storage.meshes.size(); mesh_idx++)
{ // find first mesh which has this layer
SliceMeshStorage& mesh = storage.meshes[mesh_idx];
if (int(layer_nr) <= mesh.layer_nr_max_filled_layer)
{
layer = &mesh.layers[layer_nr];
break;
}
}
if (layer != nullptr)
{
if (CommandSocket::isInstantiated())
{ // send layer info
CommandSocket::getInstance()->sendOptimizedLayerInfo(layer_nr, layer->printZ, layer_nr == 0? getSettingInMicrons("layer_height_0") : getSettingInMicrons("layer_height"));
}
}
}
log("Layer count: %i\n", storage.print_layer_count);
//layerparts2HTML(storage, "output/output.html");
Progress::messageProgressStage(Progress::Stage::SUPPORT, &time_keeper);
AreaSupport::generateSupportAreas(storage, storage.print_layer_count);
// we need to remove empty layers after we have procesed the insets
// processInsets might throw away parts if they have no wall at all (cause it doesn't fit)
// brim depends on the first layer not being empty
// only remove empty layers if we haven't generate support, because then support was added underneath the model.
// for some materials it's better to print on support than on the buildplate.
removeEmptyFirstLayers(storage, getSettingInMicrons("layer_height"), storage.print_layer_count); // changes storage.print_layer_count!
if (storage.print_layer_count == 0)
{
log("Stopping process because there are no non-empty layers.\n");
return;
}
/*
if (storage.support.generated)
{
for (unsigned int layer_idx = 0; layer_idx < storage.print_layer_count; layer_idx++)
{
Polygons& support = storage.support.supportLayers[layer_idx].supportAreas;
ExtruderTrain* infill_extr = storage.meshgroup->getExtruderTrain(storage.getSettingAsIndex("support_infill_extruder_nr"));
CommandSocket::sendPolygons(PrintFeatureType::Infill, support, 100); // infill_extr->getSettingInMicrons("support_line_width"));
}
}
*/
computePrintHeightStatistics(storage);
// handle helpers
storage.primeTower.generatePaths(storage);
logDebug("Processing ooze shield\n");
processOozeShield(storage);
logDebug("Processing draft shield\n");
processDraftShield(storage);
logDebug("Processing platform adhesion\n");
processPlatformAdhesion(storage);
// meshes post processing
for (SliceMeshStorage& mesh : storage.meshes)
{
processDerivedWallsSkinInfill(mesh);
}
}
void FffPolygonGenerator::processBasicWallsSkinInfill(SliceDataStorage& storage, unsigned int mesh_order_idx, std::vector<unsigned int>& mesh_order, ProgressStageEstimator& inset_skin_progress_estimate)
{
unsigned int mesh_idx = mesh_order[mesh_order_idx];
SliceMeshStorage& mesh = storage.meshes[mesh_idx];
size_t mesh_layer_count = mesh.layers.size();
if (mesh.getSettingBoolean("infill_mesh"))
{
processInfillMesh(storage, mesh_order_idx, mesh_order);
}
// TODO: make progress more accurate!!
// note: estimated time for insets : skins = 22.953 : 48.858
std::vector<double> walls_vs_skin_timing({22.953, 48.858});
ProgressStageEstimator* mesh_inset_skin_progress_estimator = new ProgressStageEstimator(walls_vs_skin_timing);
inset_skin_progress_estimate.nextStage(mesh_inset_skin_progress_estimator); // the stage of this function call
ProgressEstimatorLinear* inset_estimator = new ProgressEstimatorLinear(mesh_layer_count);
mesh_inset_skin_progress_estimator->nextStage(inset_estimator);
// walls
for (unsigned int layer_number = 0; layer_number < mesh.layers.size(); layer_number++)
{
logDebug("Processing insets for layer %i of %i\n", layer_number, mesh_layer_count);
processInsets(mesh, layer_number);
double progress = inset_skin_progress_estimate.progress(layer_number);
Progress::messageProgress(Progress::Stage::INSET_SKIN, progress * 100, 100);
}
ProgressEstimatorLinear* skin_estimator = new ProgressEstimatorLinear(mesh_layer_count);
mesh_inset_skin_progress_estimator->nextStage(skin_estimator);
bool process_infill = mesh.getSettingInMicrons("infill_line_distance") > 0;
if (!process_infill)
{ // do process infill anyway if it's modified by modifier meshes
for (unsigned int other_mesh_order_idx(mesh_order_idx + 1); other_mesh_order_idx < mesh_order.size(); ++other_mesh_order_idx)
{
unsigned int other_mesh_idx = mesh_order[other_mesh_order_idx];
SliceMeshStorage& other_mesh = storage.meshes[other_mesh_idx];
if (other_mesh.getSettingBoolean("infill_mesh"))
{
AABB3D aabb = storage.meshgroup->meshes[mesh_idx].getAABB();
AABB3D other_aabb = storage.meshgroup->meshes[other_mesh_idx].getAABB();
if (aabb.hit(other_aabb))
{
process_infill = true;
}
}
}
}
// skin & infill
// Progress::messageProgressStage(Progress::Stage::SKIN, &time_keeper);
int mesh_max_bottom_layer_count = 0;
if (mesh.getSettingBoolean("magic_spiralize"))
{
mesh_max_bottom_layer_count = std::max(mesh_max_bottom_layer_count, mesh.getSettingAsCount("bottom_layers"));
}
for (unsigned int layer_number = 0; layer_number < mesh.layers.size(); layer_number++)
{
logDebug("Processing skins and infill layer %i of %i\n", layer_number, mesh_layer_count);
if (!mesh.getSettingBoolean("magic_spiralize") || static_cast<int>(layer_number) < mesh_max_bottom_layer_count) //Only generate up/downskin and infill for the first X layers when spiralize is choosen.
{
processSkinsAndInfill(mesh, layer_number, process_infill);
}
double progress = inset_skin_progress_estimate.progress(layer_number);
Progress::messageProgress(Progress::Stage::INSET_SKIN, progress * 100, 100);
}
}
void FffPolygonGenerator::processInfillMesh(SliceDataStorage& storage, unsigned int mesh_order_idx, std::vector<unsigned int>& mesh_order)
{
unsigned int mesh_idx = mesh_order[mesh_order_idx];
SliceMeshStorage& mesh = storage.meshes[mesh_idx];
mesh.layer_nr_max_filled_layer = -1;
for (unsigned int layer_idx = 0; layer_idx < mesh.layers.size(); layer_idx++)
{
SliceLayer& layer = mesh.layers[layer_idx];
std::vector<PolygonsPart> new_parts;
for (unsigned int other_mesh_idx : mesh_order)
{ // limit the infill mesh's outline to within the infill of all meshes with lower order
if (other_mesh_idx == mesh_idx)
{
break; // all previous meshes have been processed
}
SliceMeshStorage& other_mesh = storage.meshes[other_mesh_idx];
if (layer_idx >= other_mesh.layers.size())
{ // there can be no interaction between the infill mesh and this other non-infill mesh
continue;
}
SliceLayer& other_layer = other_mesh.layers[layer_idx];
for (SliceLayerPart& part : layer.parts)
{
for (SliceLayerPart& other_part : other_layer.parts)
{ // limit the outline of each part of this infill mesh to the infill of parts of the other mesh with lower infill mesh order
if (!part.boundaryBox.hit(other_part.boundaryBox))
{ // early out
continue;
}
Polygons new_outline = part.outline.intersection(other_part.getOwnInfillArea());
if (new_outline.size() == 1)
{ // we don't have to call splitIntoParts, because a single polygon can only be a single part
PolygonsPart outline_part_here;
outline_part_here.add(new_outline[0]);
new_parts.push_back(outline_part_here);
}
else if (new_outline.size() > 1)
{ // we don't know whether it's a multitude of parts because of newly introduced holes, or because the polygon has been split up
std::vector<PolygonsPart> new_parts_here = new_outline.splitIntoParts();
for (PolygonsPart& new_part_here : new_parts_here)
{
new_parts.push_back(new_part_here);
}
}
// change the infill area of the non-infill mesh which is to be filled with e.g. lines
other_part.infill_area_own = other_part.getOwnInfillArea().difference(part.outline);
// note: don't change the part.infill_area, because we change the structure of that area, while the basic area in which infill is printed remains the same
// the infill area remains the same for combing
}
}
}
layer.parts.clear();
for (PolygonsPart& part : new_parts)
{
layer.parts.emplace_back();
layer.parts.back().outline = part;
layer.parts.back().boundaryBox.calculate(part);
}
if (layer.parts.size() > 0 || (mesh.getSettingAsSurfaceMode("magic_mesh_surface_mode") != ESurfaceMode::NORMAL && layer.openPolyLines.size() > 0) )
{
mesh.layer_nr_max_filled_layer = layer_idx; // last set by the highest non-empty layer
}
}
}
void FffPolygonGenerator::processDerivedWallsSkinInfill(SliceMeshStorage& mesh)
{
// create gradual infill areas
SkinInfillAreaComputation::generateGradualInfill(mesh, mesh.getSettingInMicrons("gradual_infill_step_height"), mesh.getSettingAsCount("gradual_infill_steps"));
// combine infill
unsigned int combined_infill_layers = std::max(1U, round_divide(mesh.getSettingInMicrons("infill_sparse_thickness"), std::max(getSettingInMicrons("layer_height"), 1))); //How many infill layers to combine to obtain the requested sparse thickness.
combineInfillLayers(mesh,combined_infill_layers);
// fuzzy skin
if (mesh.getSettingBoolean("magic_fuzzy_skin_enabled"))
{
processFuzzyWalls(mesh);
}
}
void FffPolygonGenerator::processInsets(SliceMeshStorage& mesh, unsigned int layer_nr)
{
SliceLayer* layer = &mesh.layers[layer_nr];
if (mesh.getSettingAsSurfaceMode("magic_mesh_surface_mode") != ESurfaceMode::SURFACE)
{
int inset_count = mesh.getSettingAsCount("wall_line_count");
if (mesh.getSettingBoolean("magic_spiralize") && static_cast<int>(layer_nr) < mesh.getSettingAsCount("bottom_layers") && ((layer_nr % 2) + 2) % 2 == 1)//Add extra insets every 2 layers when spiralizing, this makes bottoms of cups watertight.
inset_count += 5;
int line_width_x = mesh.getSettingInMicrons("wall_line_width_x");
int line_width_0 = mesh.getSettingInMicrons("wall_line_width_0");
if (mesh.getSettingBoolean("alternate_extra_perimeter"))
{
inset_count += ((layer_nr % 2) + 2) % 2;
}
bool recompute_outline_based_on_outer_wall = mesh.getSettingBoolean("support_enable");
WallsComputation walls_computation(mesh.getSettingInMicrons("wall_0_inset"), line_width_0, line_width_x, inset_count, recompute_outline_based_on_outer_wall);
walls_computation.generateInsets(layer);
}
}
void FffPolygonGenerator::removeEmptyFirstLayers(SliceDataStorage& storage, const int layer_height, unsigned int& total_layers)
{
int n_empty_first_layers = 0;
for (unsigned int layer_idx = 0; layer_idx < total_layers; layer_idx++)
{
bool layer_is_empty = true;
if (storage.support.generated && layer_idx < storage.support.supportLayers.size())
{
SupportLayer& support_layer = storage.support.supportLayers[layer_idx];
if (support_layer.supportAreas.size() > 0 || support_layer.skin.size() > 0)
{
layer_is_empty = false;
break;
}
}
for (SliceMeshStorage& mesh : storage.meshes)
{
SliceLayer& layer = mesh.layers[layer_idx];
if (layer.parts.size() > 0 || (mesh.getSettingAsSurfaceMode("magic_mesh_surface_mode") != ESurfaceMode::NORMAL && layer.openPolyLines.size() > 0) )
{
layer_is_empty = false;
break;
}
}
if (layer_is_empty)
{
n_empty_first_layers++;
} else
{
break;
}
}
if (n_empty_first_layers > 0)
{
log("Removing %d layers because they are empty\n", n_empty_first_layers);
for (SliceMeshStorage& mesh : storage.meshes)
{
std::vector<SliceLayer>& layers = mesh.layers;
layers.erase(layers.begin(), layers.begin() + n_empty_first_layers);
for (SliceLayer& layer : layers)
{
layer.printZ -= n_empty_first_layers * layer_height;
}
mesh.layer_nr_max_filled_layer -= n_empty_first_layers;
}
total_layers -= n_empty_first_layers;
storage.support.layer_nr_max_filled_layer -= n_empty_first_layers;
std::vector<SupportLayer>& support_layers = storage.support.supportLayers;
support_layers.erase(support_layers.begin(), support_layers.begin() + n_empty_first_layers);
}
}
void FffPolygonGenerator::processSkinsAndInfill(SliceMeshStorage& mesh, unsigned int layer_nr, bool process_infill)
{
if (mesh.getSettingAsSurfaceMode("magic_mesh_surface_mode") == ESurfaceMode::SURFACE)
{
return;
}
const int wall_line_count = mesh.getSettingAsCount("wall_line_count");
const int innermost_wall_line_width = (wall_line_count == 1) ? mesh.getSettingInMicrons("wall_line_width_0") : mesh.getSettingInMicrons("wall_line_width_x");
generateSkins(layer_nr, mesh, mesh.getSettingAsCount("bottom_layers"), mesh.getSettingAsCount("top_layers"), wall_line_count, innermost_wall_line_width, mesh.getSettingAsCount("skin_outline_count"), mesh.getSettingBoolean("skin_no_small_gaps_heuristic"));
if (process_infill)
{ // process infill when infill density > 0
// or when other infill meshes want to modify this infill
int infill_skin_overlap = 0;
bool infill_is_dense = mesh.getSettingInMicrons("infill_line_distance") < mesh.getSettingInMicrons("infill_line_width") + 10;
if (!infill_is_dense && mesh.getSettingAsFillMethod("infill_pattern") != EFillMethod::CONCENTRIC)
{
infill_skin_overlap = innermost_wall_line_width / 2;
}
generateInfill(layer_nr, mesh, innermost_wall_line_width, infill_skin_overlap, wall_line_count);
}
}
void FffPolygonGenerator::computePrintHeightStatistics(SliceDataStorage& storage)
{
int extruder_count = storage.meshgroup->getExtruderCount();
std::vector<int>& max_print_height_per_extruder = storage.max_print_height_per_extruder;
assert(max_print_height_per_extruder.size() == 0 && "storage.max_print_height_per_extruder shouldn't have been initialized yet!");
max_print_height_per_extruder.resize(extruder_count, -1); //Initialize all as -1.
{ // compute max_object_height_per_extruder
//Height of the meshes themselves.
for (SliceMeshStorage& mesh : storage.meshes)
{
if (mesh.getSettingBoolean("anti_overhang_mesh") || mesh.getSettingBoolean("support_mesh"))
{
continue; //Special type of mesh that doesn't get printed.
}
const unsigned int extr_nr = mesh.getSettingAsIndex("extruder_nr");
max_print_height_per_extruder[extr_nr] = std::max(max_print_height_per_extruder[extr_nr], mesh.layer_nr_max_filled_layer);
}
//Height of where the support reaches.
const unsigned int support_infill_extruder_nr = storage.getSettingAsIndex("support_infill_extruder_nr"); // TODO: support extruder should be configurable per object
max_print_height_per_extruder[support_infill_extruder_nr] =
std::max(max_print_height_per_extruder[support_infill_extruder_nr],
storage.support.layer_nr_max_filled_layer);
const unsigned int support_skin_extruder_nr = storage.getSettingAsIndex("support_interface_extruder_nr"); // TODO: support skin extruder should be configurable per object
max_print_height_per_extruder[support_skin_extruder_nr] =
std::max(max_print_height_per_extruder[support_skin_extruder_nr],
storage.support.layer_nr_max_filled_layer);
//Height of where the platform adhesion reaches.
if (storage.getSettingAsPlatformAdhesion("adhesion_type") != EPlatformAdhesion::NONE)
{
const unsigned int adhesion_extruder_nr = storage.getSettingAsIndex("adhesion_extruder_nr");
max_print_height_per_extruder[adhesion_extruder_nr] =
std::max(0, max_print_height_per_extruder[adhesion_extruder_nr]);
}
}
storage.max_print_height_order = order(max_print_height_per_extruder);
if (extruder_count >= 2)
{
int second_highest_extruder = storage.max_print_height_order[extruder_count - 2];
storage.max_print_height_second_to_last_extruder = max_print_height_per_extruder[second_highest_extruder];
}
else
{
storage.max_print_height_second_to_last_extruder = -1;
}
}
void FffPolygonGenerator::processOozeShield(SliceDataStorage& storage)
{
if (!getSettingBoolean("ooze_shield_enabled"))
{
return;
}
const int ooze_shield_dist = getSettingInMicrons("ooze_shield_dist");
for (int layer_nr = 0; layer_nr <= storage.max_print_height_second_to_last_extruder; layer_nr++)
{
storage.oozeShield.push_back(storage.getLayerOutlines(layer_nr, true).offset(ooze_shield_dist, ClipperLib::jtRound));
}
double angle = getSettingInAngleDegrees("ooze_shield_angle");
if (angle <= 89)
{
int allowed_angle_offset = tan(getSettingInAngleRadians("ooze_shield_angle")) * getSettingInMicrons("layer_height"); // Allow for a 60deg angle in the oozeShield.
for (int layer_nr = 1; layer_nr <= storage.max_print_height_second_to_last_extruder; layer_nr++)
{
storage.oozeShield[layer_nr] = storage.oozeShield[layer_nr].unionPolygons(storage.oozeShield[layer_nr - 1].offset(-allowed_angle_offset));
}
for (int layer_nr = storage.max_print_height_second_to_last_extruder; layer_nr > 0; layer_nr--)
{
storage.oozeShield[layer_nr - 1] = storage.oozeShield[layer_nr - 1].unionPolygons(storage.oozeShield[layer_nr].offset(-allowed_angle_offset));
}
}
const float largest_printed_area = 1.0; // TODO: make var a parameter, and perhaps even a setting?
for (int layer_nr = 0; layer_nr <= storage.max_print_height_second_to_last_extruder; layer_nr++)
{
storage.oozeShield[layer_nr].removeSmallAreas(largest_printed_area);
}
}
void FffPolygonGenerator::processDraftShield(SliceDataStorage& storage)
{
const unsigned int draft_shield_layers = getDraftShieldLayerCount(storage.print_layer_count);
if (draft_shield_layers <= 0)
{
return;
}
const int layer_height = getSettingInMicrons("layer_height");
const unsigned int layer_skip = 500 / layer_height + 1;
Polygons& draft_shield = storage.draft_protection_shield;
for (unsigned int layer_nr = 0; layer_nr < storage.print_layer_count && layer_nr < draft_shield_layers; layer_nr += layer_skip)
{
draft_shield = draft_shield.unionPolygons(storage.getLayerOutlines(layer_nr, true));
}
const int draft_shield_dist = getSettingInMicrons("draft_shield_dist");
storage.draft_protection_shield = draft_shield.approxConvexHull(draft_shield_dist);
}
void FffPolygonGenerator::processPlatformAdhesion(SliceDataStorage& storage)
{
SettingsBaseVirtual* train = storage.meshgroup->getExtruderTrain(getSettingBoolean("adhesion_extruder_nr"));
switch(getSettingAsPlatformAdhesion("adhesion_type"))
{
case EPlatformAdhesion::SKIRT:
{
constexpr bool outside_polygons_only = true;
SkirtBrim::generate(storage, train->getSettingInMicrons("skirt_gap"), train->getSettingAsCount("skirt_line_count"), outside_polygons_only);
}
break;
case EPlatformAdhesion::BRIM:
SkirtBrim::generate(storage, 0, train->getSettingAsCount("brim_line_count"), train->getSettingBoolean("brim_outside_only"));
break;
case EPlatformAdhesion::RAFT:
Raft::generate(storage, train->getSettingInMicrons("raft_margin"));
break;
case EPlatformAdhesion::NONE:
break;
}
}
void FffPolygonGenerator::processFuzzyWalls(SliceMeshStorage& mesh)
{
if (mesh.getSettingAsCount("wall_line_count") == 0)
{
return;
}
int64_t fuzziness = mesh.getSettingInMicrons("magic_fuzzy_skin_thickness");
int64_t avg_dist_between_points = mesh.getSettingInMicrons("magic_fuzzy_skin_point_dist");
int64_t min_dist_between_points = avg_dist_between_points * 3 / 4; // hardcoded: the point distance may vary between 3/4 and 5/4 the supplied value
int64_t range_random_point_dist = avg_dist_between_points / 2;
for (unsigned int layer_nr = 0; layer_nr < mesh.layers.size(); layer_nr++)
{
SliceLayer& layer = mesh.layers[layer_nr];
for (SliceLayerPart& part : layer.parts)
{
Polygons results;
Polygons& skin = (mesh.getSettingAsSurfaceMode("magic_mesh_surface_mode") == ESurfaceMode::SURFACE)? part.outline : part.insets[0];
for (PolygonRef poly : skin)
{
// generate points in between p0 and p1
PolygonRef result = results.newPoly();
int64_t dist_left_over = rand() % (min_dist_between_points / 2); // the distance to be traversed on the line before making the first new point
Point* p0 = &poly.back();
for (Point& p1 : poly)
{ // 'a' is the (next) new point between p0 and p1
Point p0p1 = p1 - *p0;
int64_t p0p1_size = vSize(p0p1);
int64_t dist_last_point = dist_left_over + p0p1_size * 2; // so that p0p1_size - dist_last_point evaulates to dist_left_over - p0p1_size
for (int64_t p0pa_dist = dist_left_over; p0pa_dist < p0p1_size; p0pa_dist += min_dist_between_points + rand() % range_random_point_dist)
{
int r = rand() % (fuzziness * 2) - fuzziness;
Point perp_to_p0p1 = turn90CCW(p0p1);
Point fuzz = normal(perp_to_p0p1, r);
Point pa = *p0 + normal(p0p1, p0pa_dist) + fuzz;
result.add(pa);
dist_last_point = p0pa_dist;
}
dist_left_over = p0p1_size - dist_last_point;
p0 = &p1;
}
while (result.size() < 3 )
{
unsigned int point_idx = poly.size() - 2;
result.add(poly[point_idx]);
if (point_idx == 0) { break; }
point_idx--;
}
if (result.size() < 3)
{
result.clear();
for (Point& p : poly)
result.add(p);
}
}
skin = results;
}
}
}
}//namespace cura
+174
Ver Arquivo
@@ -0,0 +1,174 @@
#ifndef FFF_AREA_GENERATOR_H
#define FFF_AREA_GENERATOR_H
#include "MeshGroup.h"
#include "utils/polygonUtils.h"
#include "utils/NoCopy.h"
#include "utils/gettime.h"
#include "settings/settings.h"
#include "sliceDataStorage.h"
#include "commandSocket.h"
#include "PrintFeature.h"
#include "progress/ProgressEstimator.h"
#include "progress/ProgressStageEstimator.h"
namespace cura
{
/*!
* Primary stage in Fused Filament Fabrication processing: Polygons are generated.
* The model is sliced and each slice consists of polygons representing the outlines: the boundaries between inside and outside the object.
* After slicing, the layers are processed; for example the wall insets are generated, and the areas which are to be filled with support and infill, which are all represented by polygons.
* In this stage nothing other than areas and circular paths are generated, which are both represented by polygons.
* No infill lines or support pattern etc. is generated.
*
* The main function of this class is FffPolygonGenerator::generateAreas().
*/
class FffPolygonGenerator : public SettingsMessenger, NoCopy
{
public:
/*!
* Basic constructor
*/
FffPolygonGenerator(SettingsBase* settings_)
: SettingsMessenger(settings_)
{
}
/*!
* Slice the \p object, process the outline information into inset perimeter polygons, support area polygons, etc.
*
* \param object The object to slice.
* \param timeKeeper Object which keeps track of timings of each stage.
* \param storage Output parameter: where the outlines are stored. See SliceLayerPart::outline.
*/
bool generateAreas(SliceDataStorage& storage, MeshGroup* object, TimeKeeper& timeKeeper);
private:
/*!
* \brief Helper function to get the actual height of the draft shield.
*
* The draft shield is the height of the print if we've set the draft shield
* limitation to FULL. Otherwise the height is set to the height limit
* setting. If the draft shield is disabled, the height is always 0.
*
* \param total_layers The total number of layers in the print (the height
* of the draft shield if the limit is FULL.
* \return The actual height of the draft shield.
*/
unsigned int getDraftShieldLayerCount(unsigned int total_layers) const;
/*!
* Slice the \p object and store the outlines in the \p storage.
*
* \param object The object to slice.
* \param timeKeeper Object which keeps track of timings of each stage.
* \param storage Output parameter: where the outlines are stored. See SliceLayerPart::outline.
*
* \return Whether the process succeeded (always true).
*/
bool sliceModel(MeshGroup* object, TimeKeeper& timeKeeper, SliceDataStorage& storage); /// slices the model
/*!
* Processes the outline information as stored in the \p storage: generates inset perimeter polygons, support area polygons, etc.
*
* \param storage Input and Output parameter: fetches the outline information (see SliceLayerPart::outline) and generates the other reachable field of the \p storage
* \param timeKeeper Object which keeps track of timings of each stage.
*/
void slices2polygons(SliceDataStorage& storage, TimeKeeper& timeKeeper);
/*!
* Processes the outline information as stored in the \p storage: generates inset perimeter polygons, skin and infill
*
* \param storage Input and Output parameter: fetches the outline information (see SliceLayerPart::outline) and generates the other reachable field of the \p storage
* \param mesh_order_idx The index of the mesh_idx in \p mesh_order to process in the vector of meshes in \p storage
* \param mesh_order The order in which the meshes are processed (used for infill meshes)
* \param inset_skin_progress_estimate The progress stage estimate calculator
*/
void processBasicWallsSkinInfill(SliceDataStorage& storage, unsigned int mesh_order_idx, std::vector<unsigned int>& mesh_order, ProgressStageEstimator& inset_skin_progress_estimate);
/*!
* Process the mesh to be an infill mesh: limit all outlines to within the infill of normal meshes and subtract their volume from the infill of those meshes
*
* \param storage Input and Output parameter: fetches the outline information (see SliceLayerPart::outline) and generates the other reachable field of the \p storage
* \param mesh_order_idx The index of the mesh_idx in \p mesh_order to process in the vector of meshes in \p storage
* \param mesh_order The order in which the meshes are processed
*/
void processInfillMesh(SliceDataStorage& storage, unsigned int mesh_order_idx, std::vector<unsigned int>& mesh_order);
/*!
* Process features which are derived from the basic walls, skin, and infill:
* fuzzy skin, infill combine
*
* \param mesh Input and Output parameter: fetches the outline information (see SliceLayerPart::outline) and generates the other reachable field of the \p storage
*/
void processDerivedWallsSkinInfill(SliceMeshStorage& mesh);
/*!
* Remove all bottom layers which are empty.
*
* \warning Changes \p total_layers
*
* \param storage Input and Ouput parameter: stores all layers
* \param layer_height The height of each layer
* \param total_layers The total number of layers
*/
void removeEmptyFirstLayers(SliceDataStorage& storage, const int layer_height, unsigned int& total_layers);
/*!
* Set \ref SliceDataStorage::max_print_height_per_extruder and \ref SliceDataStorage::max_print_height_order and \ref SliceDataStorage::max_print_height_second_to_last_extruder
*
* \param[in,out] storage Where to retrieve mesh and support etc settings from and where the print height statistics are saved.
*/
void computePrintHeightStatistics(SliceDataStorage& storage);
/*!
* Generate the inset polygons which form the walls.
* \param mesh Input and Output parameter: fetches the outline information (see SliceLayerPart::outline) and generates the other reachable field of the \p storage
* \param layer_nr The layer for which to generate the insets.
*/
void processInsets(SliceMeshStorage& mesh, unsigned int layer_nr);
/*!
* Generate the outline of the ooze shield.
* \param storage Input and Output parameter: fetches the outline information (see SliceLayerPart::outline) and generates the other reachable field of the \p storage
*/
void processOozeShield(SliceDataStorage& storage);
/*!
* Generate the skin areas.
* \param mesh Input and Output parameter: fetches the outline information (see SliceLayerPart::outline) and generates the other reachable field of the \p storage
* \param layer_nr The layer for which to generate the skin areas.
* \param process_infill Generate infill areas
*/
void processSkinsAndInfill(SliceMeshStorage& mesh, unsigned int layer_nr, bool process_infill);
/*!
* Generate the polygons where the draft screen should be.
*
* \param storage Input and Output parameter: fetches the outline information (see SliceLayerPart::outline) and generates the other reachable field of the \p storage
*/
void processDraftShield(SliceDataStorage& storage);
/*!
* Generate the skirt/brim/raft areas/insets.
* \param storage Input and Output parameter: fetches the outline information (see SliceLayerPart::outline) and generates the other reachable field of the \p storage
*/
void processPlatformAdhesion(SliceDataStorage& storage);
/*!
* Make the outer wall 'fuzzy'
*
* Introduce new vertices and move existing vertices in or out by a random distance, based on the fuzzy skin settings.
*
* This only changes the outer wall.
*
* \param[in,out] mesh where the outer wall is retrieved and stored in.
*/
void processFuzzyWalls(SliceMeshStorage& mesh);
};
}//namespace cura
#endif // FFF_AREA_GENERATOR_H
+119
Ver Arquivo
@@ -0,0 +1,119 @@
#include "FffProcessor.h"
namespace cura
{
FffProcessor FffProcessor::instance; // definition must be in cpp
FffProcessor::FffProcessor()
: polygon_generator(this)
, gcode_writer(this)
, meshgroup_number(0)
{
}
int FffProcessor::getMeshgroupNr()
{
return meshgroup_number;
}
std::string FffProcessor::getAllSettingsString(MeshGroup& meshgroup, bool first_meshgroup)
{
std::stringstream sstream;
if (first_meshgroup)
{
sstream << getAllLocalSettingsString(); // global settings
sstream << " -g";
}
else
{
sstream << " --next";
}
sstream << meshgroup.getAllLocalSettingsString();
for (int extruder_nr = 0; extruder_nr < meshgroup.getExtruderCount(); extruder_nr++)
{
ExtruderTrain* train = meshgroup.getExtruderTrain(extruder_nr);
sstream << " -e" << extruder_nr << train->getAllLocalSettingsString();
}
for (unsigned int mesh_idx = 0; mesh_idx < meshgroup.meshes.size(); mesh_idx++)
{
Mesh& mesh = meshgroup.meshes[mesh_idx];
sstream << " -e" << mesh.getSettingAsIndex("extruder_nr") << " -l \"" << mesh_idx << "\"" << mesh.getAllLocalSettingsString();
}
sstream << "\n";
return sstream.str();
}
bool FffProcessor::processMeshGroup(MeshGroup* meshgroup)
{
if (SHOW_ALL_SETTINGS) { logWarning(getAllSettingsString(*meshgroup, meshgroup_number == 0).c_str()); }
time_keeper.restart();
if (!meshgroup)
return false;
TimeKeeper time_keeper_total;
polygon_generator.setParent(meshgroup);
gcode_writer.setParent(meshgroup);
bool empty = true;
for (Mesh& mesh : meshgroup->meshes)
{
if (!mesh.getSettingBoolean("infill_mesh") && !mesh.getSettingBoolean("anti_overhang_mesh"))
{
empty = false;
}
}
if (empty)
{
Progress::messageProgress(Progress::Stage::FINISH, 1, 1); // 100% on this meshgroup
log("Total time elapsed %5.2fs.\n", time_keeper_total.restart());
profile_string += getAllSettingsString(*meshgroup, meshgroup_number == 0);
return true;
}
if (meshgroup->getSettingBoolean("wireframe_enabled"))
{
log("starting Neith Weaver...\n");
Weaver w(this);
w.weave(meshgroup);
log("starting Neith Gcode generation...\n");
Wireframe2gcode gcoder(w, gcode_writer.gcode, this);
gcoder.writeGCode();
log("finished Neith Gcode generation...\n");
} else
{
SliceDataStorage storage(meshgroup);
if (!polygon_generator.generateAreas(storage, meshgroup, time_keeper))
{
return false;
}
Progress::messageProgressStage(Progress::Stage::EXPORT, &time_keeper);
gcode_writer.writeGCode(storage, time_keeper);
}
Progress::messageProgress(Progress::Stage::FINISH, 1, 1); // 100% on this meshgroup
if (CommandSocket::isInstantiated())
{
CommandSocket::getInstance()->flushGcode();
CommandSocket::getInstance()->sendOptimizedLayerData();
}
log("Total time elapsed %5.2fs.\n", time_keeper_total.restart());
profile_string += getAllSettingsString(*meshgroup, meshgroup_number == 0);
meshgroup_number++;
polygon_generator.setParent(this); // otherwise consequent getSetting calls (e.g. for finalize) will refer to non-existent meshgroup
gcode_writer.setParent(this); // otherwise consequent getSetting calls (e.g. for finalize) will refer to non-existent meshgroup
return true;
}
} // namespace cura
+166
Ver Arquivo
@@ -0,0 +1,166 @@
#ifndef FFF_PROCESSOR_H
#define FFF_PROCESSOR_H
#include "settings/settings.h"
#include "FffGcodeWriter.h"
#include "FffPolygonGenerator.h"
#include "commandSocket.h"
#include "Weaver.h"
#include "Wireframe2gcode.h"
#include "progress/Progress.h"
#include "utils/gettime.h"
#include "utils/NoCopy.h"
#define SHOW_ALL_SETTINGS true
namespace cura {
//FusedFilamentFabrication processor. Singleton class
class FffProcessor : public SettingsBase , NoCopy
{
private:
/*!
* The FffProcessor used for the (current) slicing (The instance of this singleton)
*/
static FffProcessor instance;
FffProcessor();
public:
/*!
* Get the instance
* \return The instance
*/
static FffProcessor* getInstance()
{
return &instance;
}
/*!
* Get the index of the meshgroup currently being processed, starting at zero.
*/
int getMeshgroupNr();
private:
/*!
* The polygon generator, which slices the models and generates all polygons to be printed and areas to be filled.
*/
FffPolygonGenerator polygon_generator;
/*!
* The gcode writer, which generates paths in layer plans in a buffer, which converts these paths into gcode commands.
*/
FffGcodeWriter gcode_writer;
/*!
* The index of the meshgroup currently being processed, starting at zero.
*/
int meshgroup_number;
/*!
* A string containing all setting values passed to the engine in the format by which CuraEngine is called via the command line.
*
* Used in debugging.
*/
std::string profile_string = "";
/*!
* Get all settings for the current meshgroup in the format by which CuraEngine is called via the command line.
*
* Also includes all global settings if this is the first meshgroup.
*
* Used in debugging.
*
* \param meshgroup The meshgroup for which to stringify all settings
* \param first_meshgroup Whether this is the first meshgroup and all global settigns should be included as well
*/
std::string getAllSettingsString(MeshGroup& meshgroup, bool first_meshgroup);
public:
/*!
* Get a string containing all setting values passed to the engine in the format by which CuraEngine is called via the command line.
*
* \return A string containing all setting values passed to the engine in the format by which CuraEngine is called via the command line.
*/
std::string getProfileString() { return profile_string; }
/*!
* The stop watch used to time how long the different stages take to compute.
*/
TimeKeeper time_keeper; // TODO: use singleton time keeper
/*!
* Reset the meshgroup number to the first meshgroup to start a new slicing.
*/
void resetMeshGroupNumber()
{
meshgroup_number = 0;
}
/*!
* Set the target to write gcode to: to a file.
*
* Used when CuraEngine is used as command line tool.
*
* \param filename The filename of the file to which to write the gcode.
*/
bool setTargetFile(const char* filename)
{
return gcode_writer.setTargetFile(filename);
}
/*!
* Set the target to write gcode to: an output stream.
*
* Used when CuraEngine is NOT used as command line tool.
*
* \param stream The stream to write gcode to.
*/
void setTargetStream(std::ostream* stream)
{
return gcode_writer.setTargetStream(stream);
}
/*!
* Get the total extruded volume for a specific extruder in mm^3
*
* Retractions and unretractions don't contribute to this.
*
* \param extruder_nr The extruder number for which to get the total netto extruded volume
* \return total filament printed in mm^3
*/
double getTotalFilamentUsed(int extruder_nr)
{
return gcode_writer.getTotalFilamentUsed(extruder_nr);
}
/*!
* Get the total estimated print time in seconds
*
* \return total print time in seconds
*/
double getTotalPrintTime()
{
return gcode_writer.getTotalPrintTime();
}
/*!
* Add the end gcode and set all temperatures to zero.
*/
void finalize()
{
gcode_writer.finalize();
}
/*!
* Generate gcode for a given \p meshgroup
* The primary function of this class.
*
* \param meshgroup The meshgroup for which to generate gcode
* \return Whether this function succeeded
*/
bool processMeshGroup(MeshGroup* meshgroup);
};
}//namespace cura
#endif//FFF_PROCESSOR_H
+77
Ver Arquivo
@@ -0,0 +1,77 @@
#ifndef FLOW_TEMP_GRAPH
#define FLOW_TEMP_GRAPH
#include <cassert>
#include "utils/logoutput.h"
namespace cura
{
/*!
* Class representing a graph matching a flow to a temperature.
* The graph generally consists of several linear line segments between points at which the temperature and flow are matched.
*/
class FlowTempGraph
{
public:
struct Datum
{
double flow; //!< The flow in mm^3/s
double temp; //!< The temperature in *C
Datum(double flow, double temp)
: flow(flow)
, temp(temp)
{}
};
std::vector<Datum> data; //!< The points of the graph between which the graph is linearly interpolated
FlowTempGraph()
{}
/*!
* Get the temperature corresponding to a specific flow.
*
* For flows outside of the chart, the temperature at the minimal or maximal flow is returned.
* When the graph is empty, the @p material_print_temperature is returned.
*
* \param flow the flow in mm^3/s
* \param material_print_temperature The default printing temp (backward compatibility for when the graph fails)
* \return the corresponding temp
*/
double getTemp(double flow, double material_print_temperature, bool flow_dependent_temperature)
{
if (!flow_dependent_temperature || data.size() == 0)
{
return material_print_temperature;
}
if (data.size() == 1)
{
return data.front().temp;
}
if (flow < data.front().flow)
{
logWarning("Warning! Flow too low!\n"); // TODO
return data.front().temp;
}
Datum* last_datum = &data.front();
for (unsigned int datum_idx = 1; datum_idx < data.size(); datum_idx++)
{
Datum& datum = data[datum_idx];
if (datum.flow >= flow)
{
return last_datum->temp + (datum.temp - last_datum->temp) * (flow - last_datum->flow) / (datum.flow - last_datum->flow);
}
last_datum = &datum;
}
logWarning("Warning! Flow too high!\n"); // TODO
return data.back().temp;
};
};
} // namespace cura
#endif // FLOW_TEMP_GRAPH
+111
Ver Arquivo
@@ -0,0 +1,111 @@
/** Copyright (C) 2016 Ultimaker - Released under terms of the AGPLv3 License */
#include "utils/intpoint.h" // INT2MM
#include "GCodePathConfig.h"
namespace cura
{
GCodePathConfig::BasicConfig::BasicConfig()
: speed(0)
, acceleration(0)
, jerk(0)
, line_width(0)
, flow(100)
{
}
GCodePathConfig::BasicConfig::BasicConfig(double speed, double acceleration, double jerk, int line_width, double flow)
: speed(speed)
, acceleration(acceleration)
, jerk(jerk)
, line_width(line_width)
, flow(flow)
{
}
void GCodePathConfig::BasicConfig::set(double speed, double acceleration, double jerk, int line_width, double flow)
{
this->speed = speed;
this->acceleration = acceleration;
this->jerk = jerk;
this->line_width = line_width;
this->flow = flow;
}
GCodePathConfig::GCodePathConfig(PrintFeatureType type)
: extrusion_mm3_per_mm(0.0)
, type(type)
{
}
void GCodePathConfig::init(double speed, double acceleration, double jerk, int line_width, double flow)
{
iconic_config.set(speed, acceleration, jerk, line_width, flow);
current_config = iconic_config;
}
void GCodePathConfig::setLayerHeight(int layer_height)
{
this->layer_thickness = layer_height;
calculateExtrusion();
}
void GCodePathConfig::smoothSpeed(GCodePathConfig::BasicConfig first_layer_config, int layer_nr, double max_speed_layer)
{
current_config.speed = (iconic_config.speed * layer_nr) / max_speed_layer + (first_layer_config.speed * (max_speed_layer - layer_nr) / max_speed_layer);
current_config.acceleration = (iconic_config.acceleration * layer_nr) / max_speed_layer + (first_layer_config.acceleration * (max_speed_layer - layer_nr) / max_speed_layer);
current_config.jerk = (iconic_config.jerk * layer_nr) / max_speed_layer + (first_layer_config.jerk * (max_speed_layer - layer_nr) / max_speed_layer);
}
void GCodePathConfig::setSpeedIconic()
{
current_config.speed = iconic_config.speed;
current_config.acceleration = iconic_config.acceleration;
current_config.jerk = iconic_config.jerk;
}
double GCodePathConfig::getExtrusionMM3perMM()
{
return extrusion_mm3_per_mm;
}
double GCodePathConfig::getSpeed()
{
return current_config.speed;
}
double GCodePathConfig::getAcceleration()
{
return current_config.acceleration;
}
double GCodePathConfig::getJerk()
{
return current_config.jerk;
}
int GCodePathConfig::getLineWidth()
{
return current_config.line_width;
}
bool GCodePathConfig::isTravelPath()
{
return current_config.line_width == 0;
}
double GCodePathConfig::getFlowPercentage()
{
return current_config.flow;
}
void GCodePathConfig::calculateExtrusion()
{
extrusion_mm3_per_mm = INT2MM(current_config.line_width) * INT2MM(layer_thickness) * double(current_config.flow) / 100.0;
}
}//namespace cura
+112
Ver Arquivo
@@ -0,0 +1,112 @@
/** Copyright (C) 2016 Ultimaker - Released under terms of the AGPLv3 License */
#ifndef G_CODE_PATH_CONFIG_H
#define G_CODE_PATH_CONFIG_H
#include "RetractionConfig.h"
#include "PrintFeature.h"
namespace cura
{
/*!
* The GCodePathConfig is the configuration for moves/extrusion actions. This defines at which width the line is printed and at which speed.
*/
class GCodePathConfig
{
friend class GCodePlannerTest;
public:
/*!
* The path config settings which may change from layer to layer
*/
struct BasicConfig
{
double speed; //!< movement speed (mm/s)
double acceleration; //!< acceleration of head movement (mm/s^2)
double jerk; //!< jerk of the head movement (around stand still) (mm/s^3)
int line_width; //!< width of the line extruded
double flow; //!< extrusion flow modifier in %
BasicConfig(); //!< basic contructor initializing with inaccurate values
BasicConfig(double speed, double acceleration, double jerk, int line_width, double flow); //!< basic contructor initializing all values
void set(double speed, double acceleration, double jerk, int line_width, double flow); //!< Set all config values
};
private:
BasicConfig iconic_config; //!< The basic path configuration iconic to this print feature type
BasicConfig current_config; //!< The current path configuration for the current layer
int layer_thickness; //!< current layer height in micron
double extrusion_mm3_per_mm;//!< current mm^3 filament moved per mm line traversed
public:
const PrintFeatureType type; //!< name of the feature type
/*!
* Basic constructor.
*/
GCodePathConfig(PrintFeatureType type);
/*!
* Initialize some of the member variables.
*
* \warning GCodePathConfig::setLayerHeight still has to be called before this object can be used.
*
* \param speed The regular speed with which to print this feature
* \param line_width The line width for this feature
* \param flow The flow modifier to apply to the extruded filament when printing this feature
*/
void init(double speed, double acceleration, double jerk, int line_width, double flow);
/*!
* Set the layer height and (re)compute the extrusion_per_mm
*/
void setLayerHeight(int layer_height);
/*!
* Set the speed to somewhere between the speed of @p first_layer_config and the iconic speed.
*
* \warning This functions should not be called with @p layer_nr > @p max_speed_layer !
*
* \param first_layer_config The speed settings at layer zero
* \param layer_nr The layer number
* \param max_speed_layer The layer number for which the speed_iconic should be used.
*/
void smoothSpeed(BasicConfig first_layer_config, int layer_nr, double max_speed_layer);
/*!
* Set the speed config to the iconic speed config, i.e. the normal speed of the feature type for which this is a config.
*
* Does the same for acceleration and jerk.
*/
void setSpeedIconic();
/*!
* Can only be called after the layer height has been set (which is done while writing the gcode!)
*/
double getExtrusionMM3perMM();
/*!
* Get the movement speed in mm/s
*/
double getSpeed();
/*!
* Get the current acceleration of this config
*/
double getAcceleration();
/*!
* Get the current jerk of this config
*/
double getJerk();
int getLineWidth();
bool isTravelPath();
double getFlowPercentage();
private:
void calculateExtrusion();
};
}//namespace cura
#endif // G_CODE_PATH_CONFIG_H
+406
Ver Arquivo
@@ -0,0 +1,406 @@
/** Copyright (C) 2015 Ultimaker - Released under terms of the AGPLv3 License */
#include "LayerPlanBuffer.h"
#include "gcodeExport.h"
#include "utils/logoutput.h"
#include "FffProcessor.h"
namespace cura {
void LayerPlanBuffer::flush()
{
if (buffer.size() > 0)
{
insertTempCommands(); // insert preheat commands of the very last layer
}
while (!buffer.empty())
{
buffer.front().writeGCode(gcode);
if (CommandSocket::isInstantiated())
{
CommandSocket::getInstance()->flushGcode();
}
buffer.pop_front();
}
}
void LayerPlanBuffer::insertPreheatCommand(ExtruderPlan& extruder_plan_before, double time_after_extruder_plan_start, int extruder, double temp)
{
double acc_time = 0.0;
for (unsigned int path_idx = extruder_plan_before.paths.size() - 1; int(path_idx) != -1 ; path_idx--)
{
GCodePath& path = extruder_plan_before.paths[path_idx];
const double time_this_path = path.estimates.getTotalTime();
acc_time += time_this_path;
if (acc_time > time_after_extruder_plan_start)
{
const double time_before_path_end = acc_time - time_after_extruder_plan_start;
bool wait = false;
extruder_plan_before.insertCommand(path_idx, extruder, temp, wait, time_this_path - time_before_path_end);
return;
}
}
bool wait = false;
unsigned int path_idx = 0;
extruder_plan_before.insertCommand(path_idx, extruder, temp, wait); // insert at start of extruder plan if time_after_extruder_plan_start > extruder_plan.time
}
Preheat::WarmUpResult LayerPlanBuffer::timeBeforeExtruderPlanToInsert(std::vector<ExtruderPlan*>& extruder_plans, unsigned int extruder_plan_idx)
{
ExtruderPlan& extruder_plan = *extruder_plans[extruder_plan_idx];
int extruder = extruder_plan.extruder;
double initial_print_temp = extruder_plan.initial_printing_temperature;
double in_between_time = 0.0;
for (unsigned int extruder_plan_before_idx = extruder_plan_idx - 1; int(extruder_plan_before_idx) >= 0; extruder_plan_before_idx--)
{ // find a previous extruder plan where the same extruder is used to see what time this extruder wasn't used
ExtruderPlan& extruder_plan_before = *extruder_plans[extruder_plan_before_idx];
if (extruder_plan_before.extruder == extruder)
{
double temp_before = preheat_config.getFinalPrintTemp(extruder);
if (temp_before == 0)
{
temp_before = extruder_plan_before.printing_temperature;
}
constexpr bool during_printing = false;
Preheat::WarmUpResult warm_up = preheat_config.getWarmUpPointAfterCoolDown(in_between_time, extruder, temp_before, preheat_config.getStandbyTemp(extruder), initial_print_temp, during_printing);
warm_up.heating_time = std::min(in_between_time, warm_up.heating_time + extra_preheat_time);
return warm_up;
}
in_between_time += extruder_plan_before.estimates.getTotalTime();
}
// The last extruder plan with the same extruder falls outside of the buffer
// assume the nozzle has cooled down to strandby temperature already.
Preheat::WarmUpResult warm_up;
warm_up.total_time_window = in_between_time;
warm_up.lowest_temperature = preheat_config.getStandbyTemp(extruder);
constexpr bool during_printing = false;
warm_up.heating_time = preheat_config.getTimeToGoFromTempToTemp(extruder, warm_up.lowest_temperature, initial_print_temp, during_printing);
if (warm_up.heating_time > in_between_time)
{
warm_up.heating_time = in_between_time;
warm_up.lowest_temperature = in_between_time / preheat_config.getTimeToHeatup1Degree(extruder, during_printing);
}
warm_up.heating_time = warm_up.heating_time + extra_preheat_time;
return warm_up;
}
void LayerPlanBuffer::insertPreheatCommand_singleExtrusion(ExtruderPlan& prev_extruder_plan, int extruder, double required_temp)
{
// time_before_extruder_plan_end is halved, so that at the layer change the temperature will be half way betewen the two requested temperatures
constexpr bool during_printing = true;
double time_before_extruder_plan_end = 0.5 * preheat_config.getTimeToGoFromTempToTemp(extruder, prev_extruder_plan.printing_temperature, required_temp, during_printing);
time_before_extruder_plan_end = std::min(prev_extruder_plan.estimates.getTotalTime(), time_before_extruder_plan_end);
insertPreheatCommand(prev_extruder_plan, time_before_extruder_plan_end, extruder, required_temp);
}
void LayerPlanBuffer::handleStandbyTemp(std::vector<ExtruderPlan*>& extruder_plans, unsigned int extruder_plan_idx, double standby_temp)
{
ExtruderPlan& extruder_plan = *extruder_plans[extruder_plan_idx];
int extruder = extruder_plan.extruder;
for (unsigned int extruder_plan_before_idx = extruder_plan_idx - 2; int(extruder_plan_before_idx) >= 0; extruder_plan_before_idx--)
{
if (extruder_plans[extruder_plan_before_idx]->extruder == extruder)
{
extruder_plans[extruder_plan_before_idx + 1]->prev_extruder_standby_temp = standby_temp;
return;
}
}
logWarning("Warning: Couldn't find previous extruder plan so as to set the standby temperature. Inserting temp command in earliest available layer.\n");
ExtruderPlan& earliest_extruder_plan = *extruder_plans[0];
constexpr bool wait = false;
earliest_extruder_plan.insertCommand(0, extruder, standby_temp, wait);
}
void LayerPlanBuffer::insertPreheatCommand_multiExtrusion(std::vector<ExtruderPlan*>& extruder_plans, unsigned int extruder_plan_idx)
{
ExtruderPlan& extruder_plan = *extruder_plans[extruder_plan_idx];
int extruder = extruder_plan.extruder;
double initial_print_temp = extruder_plan.initial_printing_temperature;
Preheat::WarmUpResult heating_time_and_from_temp = timeBeforeExtruderPlanToInsert(extruder_plans, extruder_plan_idx);
if (heating_time_and_from_temp.total_time_window < preheat_config.getMinimalTimeWindow(extruder))
{
handleStandbyTemp(extruder_plans, extruder_plan_idx, initial_print_temp);
return; // don't insert preheat command and just stay on printing temperature
}
else
{
handleStandbyTemp(extruder_plans, extruder_plan_idx, heating_time_and_from_temp.lowest_temperature);
}
// handle preheat command
double time_before_extruder_plan_to_insert = heating_time_and_from_temp.heating_time;
for (unsigned int extruder_plan_before_idx = extruder_plan_idx - 1; int(extruder_plan_before_idx) >= 0; extruder_plan_before_idx--)
{
ExtruderPlan& extruder_plan_before = *extruder_plans[extruder_plan_before_idx];
assert (extruder_plan_before.extruder != extruder);
double time_here = extruder_plan_before.estimates.getTotalTime();
if (time_here >= time_before_extruder_plan_to_insert)
{
insertPreheatCommand(extruder_plan_before, time_before_extruder_plan_to_insert, extruder, initial_print_temp);
return;
}
time_before_extruder_plan_to_insert -= time_here;
}
// time_before_extruder_plan_to_insert falls before all plans in the buffer
bool wait = false;
unsigned int path_idx = 0;
extruder_plans[0]->insertCommand(path_idx, extruder, initial_print_temp, wait); // insert preheat command at verfy beginning of buffer
}
void LayerPlanBuffer::insertTempCommands(std::vector<ExtruderPlan*>& extruder_plans, unsigned int extruder_plan_idx)
{
ExtruderPlan& extruder_plan = *extruder_plans[extruder_plan_idx];
int extruder = extruder_plan.extruder;
ExtruderPlan* prev_extruder_plan = extruder_plans[extruder_plan_idx - 1];
int prev_extruder = prev_extruder_plan->extruder;
if (prev_extruder != extruder)
{ // set previous extruder to standby temperature
extruder_plan.prev_extruder_standby_temp = preheat_config.getStandbyTemp(prev_extruder);
}
if (prev_extruder == extruder)
{
insertPreheatCommand_singleExtrusion(*prev_extruder_plan, extruder, extruder_plan.printing_temperature);
prev_extruder_plan->printing_temperature_command = --prev_extruder_plan->inserts.end();
}
else
{
insertPreheatCommand_multiExtrusion(extruder_plans, extruder_plan_idx);
insertFinalPrintTempCommand(extruder_plans, extruder_plan_idx - 1);
insertPrintTempCommand(extruder_plan);
}
}
void LayerPlanBuffer::insertPrintTempCommand(ExtruderPlan& extruder_plan)
{
unsigned int extruder = extruder_plan.extruder;
double print_temp = extruder_plan.printing_temperature;
double heated_pre_travel_time = 0;
if (preheat_config.getInitialPrintTemp(extruder) != 0)
{ // handle heating from initial_print_temperature to printing_tempreature
unsigned int path_idx;
for (path_idx = 0; path_idx < extruder_plan.paths.size(); path_idx++)
{
GCodePath& path = extruder_plan.paths[path_idx];
heated_pre_travel_time += path.estimates.getTotalTime();
if (!path.isTravelPath())
{
break;
}
}
bool wait = false;
extruder_plan.insertCommand(path_idx, extruder, print_temp, wait);
}
extruder_plan.heated_pre_travel_time = heated_pre_travel_time;
}
void LayerPlanBuffer::insertFinalPrintTempCommand(std::vector<ExtruderPlan*>& extruder_plans, unsigned int last_extruder_plan_idx)
{
ExtruderPlan& last_extruder_plan = *extruder_plans[last_extruder_plan_idx];
int extruder = last_extruder_plan.extruder;
double final_print_temp = preheat_config.getFinalPrintTemp(extruder);
if (final_print_temp == 0)
{
return;
}
double heated_post_travel_time = 0; // The time after the last extrude move toward the end of the extruder plan during which the nozzle is stable at the final print temperature
{ // compute heated_post_travel_time
unsigned int path_idx;
for (path_idx = last_extruder_plan.paths.size() - 1; int(path_idx) >= 0; path_idx--)
{
GCodePath& path = last_extruder_plan.paths[path_idx];
if (!path.isTravelPath())
{
break;
}
heated_post_travel_time += path.estimates.getTotalTime();
}
}
double time_window = 0; // The time window within which the nozzle needs to heat from the initial print temp to the printing temperature and then back to the final print temp; i.e. from the first to the last extrusion move with this extruder
double weighted_average_print_temp = 0; // The average of the normal printing temperatures of the extruder plans (which might be different due to flow dependent temp or due to initial layer temp) Weighted by time
double initial_print_temp = -1; // The initial print temp of the first extruder plan with this extruder
{ // compute time window and print temp statistics
double heated_pre_travel_time = -1; // The time before the first extrude move from the start of the extruder plan during which the nozzle is stable at the initial print temperature
for (unsigned int prev_extruder_plan_idx = last_extruder_plan_idx; (int)prev_extruder_plan_idx >= 0; prev_extruder_plan_idx--)
{
ExtruderPlan& prev_extruder_plan = *extruder_plans[prev_extruder_plan_idx];
if (prev_extruder_plan.extruder != extruder)
{
break;
}
double prev_extruder_plan_time = prev_extruder_plan.estimates.getTotalTime();
time_window += prev_extruder_plan_time;
heated_pre_travel_time = prev_extruder_plan.heated_pre_travel_time;
if (prev_extruder_plan.estimates.getTotalUnretractedTime() > 0 && prev_extruder_plan.estimates.getMaterial() > 0)
{ // handle temp statistics
assert(prev_extruder_plan.printing_temperature != -1 && "Previous extruder plan should already have a temperature planned");
weighted_average_print_temp += prev_extruder_plan.printing_temperature * prev_extruder_plan_time;
initial_print_temp = prev_extruder_plan.initial_printing_temperature;
}
}
weighted_average_print_temp /= time_window;
time_window -= heated_pre_travel_time + heated_post_travel_time;
assert(heated_pre_travel_time != -1 && "heated_pre_travel_time must have been computed; there must have been an extruder plan!");
}
assert((time_window >= 0 || last_extruder_plan.estimates.getMaterial() == 0) && "Time window should always be positive if we actually extrude");
// ,layer change .
// : ,precool command ,layer change .
// : ____: : ,precool command .
// :/ \ _____:_____: .
// _____/ \ / \ .
// / \ / \ .
// / / .
// / / .
// .
// approximate ^ by ^ .
// This approximation is quite ok since it only determines where to insert the precool temp command,
// which means the stable temperature of the previous extruder plan and the stable temperature of the next extruder plan couldn't be reached
constexpr bool during_printing = true;
Preheat::CoolDownResult warm_cool_result = preheat_config.getCoolDownPointAfterWarmUp(time_window, extruder, initial_print_temp, weighted_average_print_temp, final_print_temp, during_printing);
double cool_down_time = warm_cool_result.cooling_time;
assert(cool_down_time >= 0);
// find extruder plan in which to insert cooling command
ExtruderPlan* precool_extruder_plan = &last_extruder_plan;
{
for (unsigned int precool_extruder_plan_idx = last_extruder_plan_idx; (int)precool_extruder_plan_idx >= 0; precool_extruder_plan_idx--)
{
precool_extruder_plan = extruder_plans[precool_extruder_plan_idx];
if (precool_extruder_plan->printing_temperature_command)
{ // the precool command ends up before the command to go to the print temperature of the next extruder plan, so remove that print temp command
precool_extruder_plan->inserts.erase(*precool_extruder_plan->printing_temperature_command);
}
double time_here = precool_extruder_plan->estimates.getTotalTime();
if (cool_down_time < time_here)
{
break;
}
cool_down_time -= time_here;
}
}
// at this point cool_down_time is what time is left if cool down time of extruder plans after precool_extruder_plan (up until last_extruder_plan) are already taken into account
{ // insert temp command in precool_extruder_plan
double extrusion_time_seen = 0;
unsigned int path_idx;
for (path_idx = precool_extruder_plan->paths.size() - 1; int(path_idx) >= 0; path_idx--)
{
GCodePath& path = precool_extruder_plan->paths[path_idx];
extrusion_time_seen += path.estimates.getTotalTime();
if (extrusion_time_seen >= cool_down_time)
{
break;
}
}
bool wait = false;
double time_after_path_start = extrusion_time_seen - cool_down_time;
precool_extruder_plan->insertCommand(path_idx, extruder, final_print_temp, wait, time_after_path_start);
}
}
void LayerPlanBuffer::insertTempCommands()
{
if (buffer.back().extruder_plans.size() == 0 || (buffer.back().extruder_plans.size() == 1 && buffer.back().extruder_plans[0].paths.size() == 0))
{ // disregard empty layer
buffer.pop_back();
return;
}
std::vector<ExtruderPlan*> extruder_plans;
extruder_plans.reserve(buffer.size() * 2);
for (GCodePlanner& layer_plan : buffer)
{
for (ExtruderPlan& extr_plan : layer_plan.extruder_plans)
{
extruder_plans.push_back(&extr_plan);
}
}
// insert commands for all extruder plans on this layer
GCodePlanner& layer_plan = buffer.back();
for (unsigned int extruder_plan_idx = 0; extruder_plan_idx < layer_plan.extruder_plans.size(); extruder_plan_idx++)
{
unsigned int overall_extruder_plan_idx = extruder_plans.size() - layer_plan.extruder_plans.size() + extruder_plan_idx;
ExtruderPlan& extruder_plan = layer_plan.extruder_plans[extruder_plan_idx];
int extruder = extruder_plan.extruder;
double time = extruder_plan.estimates.getTotalUnretractedTime();
if (time <= 0.0
|| extruder_plan.estimates.getMaterial() == 0.0 // extruder plan only consists of moves (when an extruder switch occurs at the beginning of a layer)
)
{
continue;
}
double avg_flow = extruder_plan.estimates.getMaterial() / time;
extruder_plan.printing_temperature = preheat_config.getTemp(extruder, avg_flow, extruder_plan.is_initial_layer);
extruder_plan.initial_printing_temperature = preheat_config.getInitialPrintTemp(extruder);
if (extruder_plan.initial_printing_temperature == 0
|| !extruder_used_in_meshgroup[extruder]
|| (overall_extruder_plan_idx > 0 && extruder_plans[overall_extruder_plan_idx - 1]->extruder == extruder)
)
{
extruder_plan.initial_printing_temperature = extruder_plan.printing_temperature;
extruder_used_in_meshgroup[extruder] = true;
}
assert(extruder_plan.printing_temperature != -1 && "extruder_plan.printing_temperature should now have been set");
if (buffer.size() == 1 && extruder_plan_idx == 0)
{ // the very first extruder plan of the current meshgroup
int extruder = extruder_plan.extruder;
for (int extruder_idx = 0; extruder_idx < getSettingAsCount("machine_extruder_count"); extruder_idx++)
{ // set temperature of the first nozzle, turn other nozzles down
if (FffProcessor::getInstance()->getMeshgroupNr() == 0)
{
// override values from GCodeExport::setInitialTemps
// the first used extruder should be set to the required temp in the start gcode
// see FffGcodeWriter::processStartingCode
if (extruder_idx == extruder)
{
gcode.setInitialTemp(extruder_idx, extruder_plan.printing_temperature);
}
else
{
gcode.setInitialTemp(extruder_idx, preheat_config.getStandbyTemp(extruder_idx));
}
}
else
{
if (extruder_idx != extruder)
{ // TODO: do we need to do this?
extruder_plan.prev_extruder_standby_temp = preheat_config.getStandbyTemp(extruder_idx);
}
}
}
continue;
}
insertTempCommands(extruder_plans, overall_extruder_plan_idx);
}
}
} // namespace cura
+181
Ver Arquivo
@@ -0,0 +1,181 @@
/** Copyright (C) 2016 Ultimaker - Released under terms of the AGPLv3 License */
#ifndef LAYER_PLAN_BUFFER_H
#define LAYER_PLAN_BUFFER_H
#include <list>
#include "settings/settings.h"
#include "commandSocket.h"
#include "gcodeExport.h"
#include "gcodePlanner.h"
#include "MeshGroup.h"
#include "Preheat.h"
namespace cura
{
/*!
* Class for buffering multiple layer plans (\ref GCodePlanner) / extruder plans within those layer plans, so that temperature commands can be inserted in earlier layer plans.
*
* This class handles where to insert temperature commands for:
* - initial layer temperature
* - flow dependent temperature
* - starting to heat up from the standby temperature
* - initial printing temperature | printing temperature | final printing temperature
*
* \image html assets/precool.png "Temperature Regulation" width=10cm
* \image latex assets/precool.png "Temperature Regulation" width=10cm
*
*/
class LayerPlanBuffer : SettingsMessenger
{
GCodeExport& gcode;
Preheat preheat_config; //!< the nozzle and material temperature settings for each extruder train.
static constexpr unsigned int buffer_size = 5; // should be as low as possible while still allowing enough time in the buffer to heat up from standby temp to printing temp // TODO: hardcoded value
// this value should be higher than 1, cause otherwise each layer is viewed as the first layer and no temp commands are inserted.
static constexpr const double extra_preheat_time = 1.0; //!< Time to start heating earlier than computed to avoid accummulative discrepancy between actual heating times and computed ones.
std::vector<bool> extruder_used_in_meshgroup; //!< For each extruder whether it has already been planned once in this meshgroup. This is used to see whether we should heat to the initial_print_temp or to the printing_temperature
public:
std::list<GCodePlanner> buffer; //!< The buffer containing several layer plans (GCodePlanner) before writing them to gcode.
LayerPlanBuffer(SettingsBaseVirtual* settings, GCodeExport& gcode)
: SettingsMessenger(settings)
, gcode(gcode)
, extruder_used_in_meshgroup(MAX_EXTRUDERS, false)
{ }
void setPreheatConfig(MeshGroup& settings)
{
preheat_config.setConfig(settings);
}
/*!
* Place a new layer plan (GcodePlanner) by constructing it with the given arguments.
* Pop back the oldest layer plan is it exceeds the buffer size and write it to gcode.
*/
template<typename... Args>
GCodePlanner& emplace_back(Args&&... constructor_args)
{
if (buffer.size() > 0)
{
insertTempCommands(); // insert preheat commands of the just completed layer plan (not the newly emplaced one)
}
buffer.emplace_back(constructor_args...);
if (buffer.size() > buffer_size)
{
buffer.front().writeGCode(gcode);
if (CommandSocket::isInstantiated())
{
CommandSocket::getInstance()->flushGcode();
}
buffer.pop_front();
}
return buffer.back();
}
/*!
* Write all remaining layer plans (GCodePlanner) to gcode and empty the buffer.
*/
void flush();
private:
/*!
* Insert the preheat command for @p extruder into @p extruder_plan_before
*
* \param extruder_plan_before An extruder plan before the extruder plan for which the temperature is computed, in which to insert the preheat command
* \param time_before_extruder_plan_end The time before the end of the extruder plan, before which to insert the preheat command
* \param extruder The extruder for which to set the temperature
* \param temp The temperature of the preheat command
*/
void insertPreheatCommand(ExtruderPlan& extruder_plan_before, double time_before_extruder_plan_end, int extruder, double temp);
/*!
* Compute the time needed to preheat, based either on the time the extruder has been on standby
* or based on the temp of the previous extruder plan which has the same extruder nr.
*
* \param extruder_plans The extruder plans in the buffer, moved to a temporary vector (from lower to upper layers)
* \param extruder_plan_idx The index of the extruder plan in \p extruder_plans for which to find the preheat time needed
* \return the time needed to preheat and the temperature from which heating starts
*/
Preheat::WarmUpResult timeBeforeExtruderPlanToInsert(std::vector<ExtruderPlan*>& extruder_plans, unsigned int extruder_plan_idx);
/*!
* For two consecutive extruder plans of the same extruder (so on different layers),
* preheat the extruder to the temperature corresponding to the average flow of the second extruder plan.
*
* The preheat commands are inserted such that the middle of the temperature change coincides with the start of the next layer.
*
* \param prev_extruder_plan The former extruder plan (of the former layer)
* \param extruder The extruder for which too set the temperature
* \param required_temp The required temperature for the second extruder plan
*/
void insertPreheatCommand_singleExtrusion(ExtruderPlan& prev_extruder_plan, int extruder, double required_temp);
/*!
* Insert the preheat command for an extruder plan which is preceded by an extruder plan with a different extruder.
* Find the time window in which this extruder hasn't been used
* and compute at what time the preheat command needs to be inserted.
* Then insert the preheat command in the right extruder plan.
*
* \param extruder_plans The extruder plans in the buffer, moved to a temporary vector (from lower to upper layers)
* \param extruder_plan_idx The index of the extruder plan in \p extruder_plans for which to find the preheat time needed
*/
void insertPreheatCommand_multiExtrusion(std::vector<ExtruderPlan*>& extruder_plans, unsigned int extruder_plan_idx);
/*!
* Insert the preheat command for the extruder plan corersponding to @p extruder_plan_idx of the layer corresponding to @p layer_plan_idx.
*
* \param extruder_plans The extruder plans in the buffer, moved to a temporary vector (from lower to upper layers)
* \param extruder_plan_idx The index of the extruder plan in \p extruder_plans for which to generate the preheat command
*/
void insertTempCommands(std::vector<ExtruderPlan*>& extruder_plans, unsigned int extruder_plan_idx);
/*!
* Insert the temperature command to heat from the initial print temperature to the printing temperature
*
* The temperature command is insert at the start of the very first extrusion move
*
* \param extruder_plan The extruder plan in which to insert the heat up command
*/
void insertPrintTempCommand(ExtruderPlan& extruder_plan);
/*!
* Insert the temp command to start cooling from the printing temperature to the final print temp
*
* The print temp is inserted before the last extrusion move of the extruder plan corresponding to \p last_extruder_plan_idx
*
* The command is inserted at a timed offset before the end of the last extrusion move
*
* \param extruder_plans The extruder plans in the buffer, moved to a temporary vector (from lower to upper layers)
* \param last_extruder_plan_idx The index of the last extruder plan in \p extruder_plans with the same extruder as previous extruder plans
*/
void insertFinalPrintTempCommand(std::vector<ExtruderPlan*>& extruder_plans, unsigned int last_extruder_plan_idx);
/*!
* Insert the preheat commands for the last added layer (unless that layer was empty)
*/
void insertTempCommands();
/*!
* Reconfigure the standby temperature during which we didn't print with this extruder.
* Find the previous extruder plan with the same extruder as layers[layer_plan_idx].extruder_plans[extruder_plan_idx]
* Set the prev_extruder_standby_temp in the next extruder plan
*
* \param extruder_plans The extruder plans in the buffer, moved to a temporary vector (from lower to upper layers)
* \param extruder_plan_idx The index of the extruder plan in \p extruder_plans before which to reconfigure the standby temperature
* \param standby_temp The temperature to which to cool down when the extruder is in standby mode.
*/
void handleStandbyTemp(std::vector<ExtruderPlan*>& extruder_plans, unsigned int extruder_plan_idx, double standby_temp);
};
} // namespace cura
#endif // LAYER_PLAN_BUFFER_H
+234
Ver Arquivo
@@ -0,0 +1,234 @@
#include "MergeInfillLines.h"
#include <algorithm> // min
#include "utils/linearAlg2D.h"
namespace cura
{
void MergeInfillLines::writeCompensatedMove(Point& to, double speed, GCodePath& last_path, int64_t new_line_width)
{
double old_line_width = INT2MM(last_path.config->getLineWidth());
double new_line_width_mm = INT2MM(new_line_width);
double extrusion_mod = new_line_width_mm / old_line_width;
double new_speed = speed;
if (speed_equalize_flow_enabled)
{
double speed_mod = old_line_width / new_line_width_mm;
new_speed = std::min(speed * speed_mod, speed_equalize_flow_max);
}
sendLineTo(last_path.config->type, to, last_path.getLineWidth());
gcode.writeMove(to, new_speed, last_path.getExtrusionMM3perMM() * extrusion_mod);
}
bool MergeInfillLines::mergeInfillLines(unsigned int& path_idx)
{ //Check for lots of small moves and combine them into one large line
Point prev_middle;
Point last_middle;
int64_t line_width;
if (isConvertible(path_idx, prev_middle, last_middle, line_width, false))
{
// path_idx + 3 is the index of the second extrusion move to be converted in combination with the first
{
GCodePath& move_path = paths[path_idx];
for(unsigned int point_idx = 0; point_idx < move_path.points.size() - 1; point_idx++)
{
gcode.writeMove(move_path.points[point_idx], move_path.config->getSpeed() * extruder_plan.getTravelSpeedFactor(), move_path.getExtrusionMM3perMM());
}
gcode.writeMove(prev_middle, travelConfig.getSpeed(), 0);
GCodePath& last_path = paths[path_idx + 3];
writeCompensatedMove(last_middle, last_path.config->getSpeed() * extruder_plan.getExtrudeSpeedFactor(), last_path, line_width);
}
path_idx += 2;
extruder_plan.handleInserts(path_idx, gcode);
for (; isConvertible(path_idx, prev_middle, last_middle, line_width, true); path_idx += 2)
{
extruder_plan.handleInserts(path_idx, gcode);
GCodePath& last_path = paths[path_idx + 3];
writeCompensatedMove(last_middle, last_path.config->getSpeed() * extruder_plan.getExtrudeSpeedFactor(), last_path, line_width);
}
path_idx = path_idx + 1; // means that the next path considered is the travel path after the converted extrusion path corresponding to the updated path_idx
extruder_plan.handleInserts(path_idx, gcode);
return true;
}
return false;
};
bool MergeInfillLines::isConvertible(unsigned int path_idx_first_move, Point& first_middle, Point& second_middle, int64_t& resulting_line_width, bool use_second_middle_as_first)
{
unsigned int idx = path_idx_first_move;
if (idx + 3 > paths.size()-1)
{
return false;
}
if ( paths[idx+0].config != &travelConfig // must be travel
|| paths[idx+1].points.size() > 1 // extrusion path is single line
|| paths[idx+1].config == &travelConfig // must be extrusion
// || paths[idx+2].points.size() > 1 // travel must be direct
|| paths[idx+2].config != &travelConfig // must be travel
|| paths[idx+3].points.size() > 1 // extrusion path is single line
|| paths[idx+3].config == &travelConfig // must be extrusion
|| paths[idx+1].config != paths[idx+3].config // both extrusion moves should have the same config
)
{
return false;
}
if (!(paths[idx+1].config->type == PrintFeatureType::Infill || paths[idx+1].config->type == PrintFeatureType::Skin))
{ // only (skin) infill lines can be merged (note that the second extrusion line config is already checked to be the same as the first in code above)
return false;
}
if (paths[idx+1].space_fill_type != SpaceFillType::Lines || paths[idx+3].space_fill_type != SpaceFillType::Lines)
{ // both extrusion moves must be of lines space filling type!
return false;
}
int64_t line_width = paths[idx+1].config->getLineWidth();
Point& a = paths[idx+0].points.back(); // first extruded line from
Point& b = paths[idx+1].points.back(); // first extruded line to
Point& c = paths[idx+2].points.back(); // second extruded line from
Point& d = paths[idx+3].points.back(); // second extruded line to
return isConvertible(a, b, c, d, line_width, first_middle, second_middle, resulting_line_width, use_second_middle_as_first);
}
bool MergeInfillLines::isConvertible(const Point& a, const Point& b, const Point& c, const Point& d, int64_t line_width, Point& first_middle, Point& second_middle, int64_t& resulting_line_width, bool use_second_middle_as_first)
{
use_second_middle_as_first = false;
int64_t max_line_width = nozzle_size * 3 / 2;
Point ab = b - a;
Point cd = d - c;
if (b == c)
{
return false; // the line segments are connected!
}
int64_t ab_size = vSize(ab);
int64_t cd_size = vSize(cd);
if (ab_size > nozzle_size * 5 || cd_size > nozzle_size * 5)
{
return false; // infill lines are too long; otherwise infill lines might be merged when the next infill line is coincidentally shorter like |, would become \ ...
}
// if the lines are in the same direction then abs( dot(ab,cd) / |ab| / |cd| ) == 1
int64_t prod = dot(ab,cd);
if (std::abs(prod) + 400 < ab_size * cd_size) // 400 = 20*20, where 20 micron is the allowed inaccuracy in the dot product, introduced by the inaccurate point locations of a,b,c,d
{
return false; // extrusion moves not in the same or opposite diraction
}
// make lines in the same direction by flipping one
if (prod < 0)
{
ab = ab * -1;
}
else if (prod == 0)
{
return false; // lines are orthogonal!
}
else if (b == d || a == c)
{
return false; // the line segments are connected!
}
first_middle = (use_second_middle_as_first)?
second_middle :
(a + b) / 2;
second_middle = (c + d) / 2;
Point dir_vector_perp = turn90CCW(second_middle - first_middle);
int64_t dir_vector_perp_length = vSize(dir_vector_perp); // == dir_vector_length
if (dir_vector_perp_length == 0)
{
return false;
}
if (dir_vector_perp_length > 5 * nozzle_size)
{
return false; // infill lines too far apart
}
Point infill_vector = (cd + ab) / 2; // (similar to) average line / direction of the infill
// compute the resulting line width
resulting_line_width = std::abs( dot(dir_vector_perp, infill_vector) / dir_vector_perp_length );
if (resulting_line_width > max_line_width)
{
return false; // combined lines would be too wide
}
if (resulting_line_width == 0)
{
return false; // dot is zero, so lines are in each others extension, not next to eachother
}
// check whether two lines are adjacent (note: not 'line segments' but 'lines')
Point ac = c - first_middle;
Point infill_vector_perp = turn90CCW(infill_vector);
int64_t perp_proj = dot(ac, infill_vector_perp);
int64_t infill_vector_perp_length = vSize(infill_vector_perp);
if (std::abs(std::abs(perp_proj) / infill_vector_perp_length - line_width) > 20) // it should be the case that dot(ac, infill_vector_perp) / |infill_vector_perp| == line_width
{
return false; // lines are too far apart or too close together
}
// check whether the two line segments are adjacent.
// full infill in a narrow area might result in line segments with arbitrary distance between them
// the more the narrow passage in the area gets aligned with the infill direction, the further apart the line segments will be
// however, distant line segments might also be due to different narrow passages, so we limit the distance between merged line segments.
if (!LinearAlg2D::lineSegmentsAreCloserThan(a, b, c, d, line_width * 2))
{
return false;
}
return true;
};
/*
void MergeInfillLines::merge(Point& from, Point& p0, Point& p1)
{ //Check for lots of small moves and combine them into one large line
if (path->points.size() == 1 && path->config != &travelConfig); // && shorterThen(from - path->points[0], path->config->getLineWidth() * 2))
{
Point p0 = path->points[0];
unsigned int path_idx_last = path_idx + 1; // index of the last short move
while(path_idx_last < paths.size() && paths[path_idx_last].points.size() == 1 && shorterThen(p0 - paths[path_idx_last].points[0], path->config->getLineWidth() * 2))
{
p0 = paths[path_idx_last].points[0];
path_idx_last ++;
}
if (paths[path_idx_last-1].config == &travelConfig)
path_idx_last --;
if (path_idx_last > path_idx + 2)
{
p0 = from;
for(unsigned int path_idx_short = path_idx; path_idx_short < path_idx_last-1; path_idx_short+=2)
{
int64_t oldLen = vSize(p0 - paths[path_idx_short].points[0]);
Point newPoint = (paths[path_idx_short].points[0] + paths[path_idx_short+1].points[0]) / 2;
int64_t newLen = vSize(from - newPoint);
if (newLen > 0)
{
if (oldLen > 0)
gcode.writeMove(newPoint, speed * oldLen / newLen, path->getExtrusionMM3perMM() * newLen / oldLen);
else
gcode.writeMove(newPoint, speed, path->getExtrusionMM3perMM());
}
}
gcode.writeMove(paths[path_idx_last-1].points[0], speed, path->getExtrusionMM3perMM());
path_idx = path_idx_last - 1;
continue;
}
}
}*/
}//namespace cura
+93
Ver Arquivo
@@ -0,0 +1,93 @@
#ifndef MERGE_INFILL_LINES_H
#define MERGE_INFILL_LINES_H
#include "utils/intpoint.h"
#include "gcodeExport.h"
#include "gcodePlanner.h"
#include "GCodePathConfig.h"
namespace cura
{
class MergeInfillLines
{
// void merge(Point& from, Point& p0, Point& p1);
GCodeExport& gcode; //!< Where to write the combined line to
int layer_nr; //!< The current layer number
std::vector<GCodePath>& paths; //!< The paths currently under consideration
ExtruderPlan& extruder_plan; //!< The extruder plan of the paths currently under consideration
GCodePathConfig& travelConfig; //!< The travel settings used to see whether a path is a travel path or an extrusion path
int64_t nozzle_size; //!< The diameter of the hole in the nozzle
bool speed_equalize_flow_enabled; //!< Should the speed be varied with extrusion width
double speed_equalize_flow_max; //!< Maximum speed when adjusting speed for flow
/*!
* Whether the next two extrusion paths are convertible to a single line segment, starting from the end point the of the last travel move at \p path_idx_first_move
* \param path_idx_first_move Index into MergeInfillLines::paths to the travel before the two extrusion moves udner consideration
* \param first_middle Output parameter: the middle of the first extrusion move
* \param second_middle Input/Output parameter: outputs the middle of the second extrusion move; inputs \p first_middle so we don't have to compute it
* \param resulting_line_width Output parameter: The width of the resulting combined line (the average length of the lines combined)
* \param use_second_middle_as_first Whether to use \p second_middle as input parameter for \p first_middle
* \return Whether the next two extrusion paths are convertible to a single line segment, starting from the end point the of the last travel move at \p path_idx_first_move
*/
bool isConvertible(unsigned int path_idx_first_move, Point& first_middle, Point& second_middle, int64_t& resulting_line_width, bool use_second_middle_as_first = false);
/*!
* Whether the two consecutive extrusion paths (ab and cd) are convitrible to a single line segment.
*
* Note: as an optimization the \p second_middle from the previous call to isConvertible can be used for \p first_middle, instead of recomputing it.
*
* \param a first from
* \param b first to
* \param c second from
* \param d second to
* \param line_width The line width of the moves
* \param first_middle Output parameter: the middle of the first extrusion move
* \param second_middle Input/Output parameter: outputs the middle of the second extrusion move; inputs \p first_middle so we don't have to compute it
* \param resulting_line_width Output parameter: The width of the resulting combined line (the average length of the lines combined)
* \param use_second_middle_as_first Whether to use \p second_middle as input parameter for \p first_middle
* \return Whether the next two extrusion paths are convertible to a single line segment, starting from the end point the of the last travel move at \p path_idx_first_move
*/
bool isConvertible(const Point& a, const Point& b, const Point& c, const Point& d, int64_t line_width, Point& first_middle, Point& second_middle, int64_t& resulting_line_width, bool use_second_middle_as_first = false);
/*!
* Write an extrusion move with compensated width and compensated speed so that the material flow will be the same.
*
* \param to The point to move to
* \param speed The original speed
* \param old_path The original path
* \param new_line_width The width of the convewrted line (approximately the length of the original line)
*/
void writeCompensatedMove(Point& to, double speed, GCodePath& old_path, int64_t new_line_width);
public:
/*!
* Simple constructor only used by MergeInfillLines::isConvertible to easily convey the environment
*/
MergeInfillLines(GCodeExport& gcode, int layer_nr, std::vector<GCodePath>& paths, ExtruderPlan& extruder_plan, GCodePathConfig& travelConfig, int64_t nozzle_size, bool speed_equalize_flow_enabled, double speed_equalize_flow_max)
: gcode(gcode), layer_nr(layer_nr), paths(paths), extruder_plan(extruder_plan), travelConfig(travelConfig), nozzle_size(nozzle_size), speed_equalize_flow_enabled(speed_equalize_flow_enabled), speed_equalize_flow_max(speed_equalize_flow_max) { }
/*!
* Check for lots of small moves and combine them into one large line.
* Updates \p path_idx to the next path which is not combined.
*
* \param gcode Where to write the combined line to
* \param paths The paths currently under consideration
* \param travelConfig The travel settings used to see whether a path is a travel path or an extrusion path
* \param nozzle_size The diameter of the hole in the nozzle
* \param path_idx Input/Output parameter: The current index in \p paths where to start combining and the current index after combining as output parameter.
* \return Whether lines have been merged and normal path-to-gcode generation can be skipped for the current resulting \p path_idx .
*/
bool mergeInfillLines(unsigned int& path_idx);
/*!
* send a line segment through the command socket from the previous point to the given point \p to
*/
void sendLineTo(PrintFeatureType print_feature_type, Point to, int line_width)
{
CommandSocket::sendLineTo(print_feature_type, to, line_width);
}
};
}//namespace cura
#endif // MERGE_INFILL_LINES_H
+349
Ver Arquivo
@@ -0,0 +1,349 @@
/** Copyright (C) 2013 David Braam - Released under terms of the AGPLv3 License */
#include <string.h>
#include <strings.h>
#include <stdio.h>
#include "MeshGroup.h"
#include "utils/gettime.h"
#include "utils/logoutput.h"
#include "utils/string.h"
#include "settings/SettingRegistry.h" // loadExtruderJSONsettings
namespace cura
{
FILE* binaryMeshBlob = nullptr;
/* Custom fgets function to support Mac line-ends in Ascii STL files. OpenSCAD produces this when used on Mac */
void* fgets_(char* ptr, size_t len, FILE* f)
{
while(len && fread(ptr, 1, 1, f) > 0)
{
if (*ptr == '\n' || *ptr == '\r')
{
*ptr = '\0';
return ptr;
}
ptr++;
len--;
}
return nullptr;
}
MeshGroup::MeshGroup(SettingsBaseVirtual* settings_base)
: SettingsBase(settings_base)
, extruder_count(-1)
{}
MeshGroup::~MeshGroup()
{
for (unsigned int extruder = 0; extruder < MAX_EXTRUDERS; extruder++)
{
if (extruders[extruder])
{
delete extruders[extruder];
}
}
}
int MeshGroup::getExtruderCount() const
{
if (extruder_count == -1)
{
extruder_count = getSettingAsCount("machine_extruder_count");
}
return extruder_count;
}
ExtruderTrain* MeshGroup::createExtruderTrain(unsigned int extruder_nr)
{
if (!extruders[extruder_nr])
{
extruders[extruder_nr] = new ExtruderTrain(this, extruder_nr);
int err = SettingRegistry::getInstance()->loadExtruderJSONsettings(extruder_nr, extruders[extruder_nr]);
if (err)
{
logError("Couldn't load extruder.def.json for extruder %i\n", extruder_nr);
std::exit(1);
}
}
return extruders[extruder_nr];
}
ExtruderTrain* MeshGroup::getExtruderTrain(unsigned int extruder_nr)
{
assert(extruders[extruder_nr]);
return extruders[extruder_nr];
}
const ExtruderTrain* MeshGroup::getExtruderTrain(unsigned int extruder_nr) const
{
assert(extruders[extruder_nr]);
return extruders[extruder_nr];
}
Point3 MeshGroup::min() const
{
if (meshes.size() < 1)
{
return Point3(0, 0, 0);
}
Point3 ret = meshes[0].min();
for(unsigned int i=1; i<meshes.size(); i++)
{
Point3 v = meshes[i].min();
ret.x = std::min(ret.x, v.x);
ret.y = std::min(ret.y, v.y);
ret.z = std::min(ret.z, v.z);
}
return ret;
}
Point3 MeshGroup::max() const
{
if (meshes.size() < 1)
{
return Point3(0, 0, 0);
}
Point3 ret = meshes[0].max();
for(unsigned int i=1; i<meshes.size(); i++)
{
Point3 v = meshes[i].max();
ret.x = std::max(ret.x, v.x);
ret.y = std::max(ret.y, v.y);
ret.z = std::max(ret.z, v.z);
}
return ret;
}
void MeshGroup::clear()
{
for(Mesh& m : meshes)
{
m.clear();
}
}
void MeshGroup::finalize()
{
extruder_count = getSettingAsCount("machine_extruder_count");
for (int extruder_nr = 0; extruder_nr < extruder_count; extruder_nr++)
{
createExtruderTrain(extruder_nr); // create it if it didn't exist yet
if (getSettingAsIndex("adhesion_extruder_nr") == extruder_nr && getSettingAsPlatformAdhesion("adhesion_type") != EPlatformAdhesion::NONE)
{
getExtruderTrain(extruder_nr)->setIsUsed(true);
continue;
}
for (const Mesh& mesh : meshes)
{
if (mesh.getSettingBoolean("support_enable")
&& (
getSettingAsIndex("support_infill_extruder_nr") == extruder_nr
|| getSettingAsIndex("support_extruder_nr_layer_0") == extruder_nr
|| (getSettingBoolean("support_interface_enable") && getSettingAsIndex("support_interface_extruder_nr") == extruder_nr)
)
)
{
getExtruderTrain(extruder_nr)->setIsUsed(true);
break;
}
}
}
for (const Mesh& mesh : meshes)
{
if (!mesh.getSettingBoolean("anti_overhang_mesh")
&& !mesh.getSettingBoolean("support_mesh")
)
{
getExtruderTrain(mesh.getSettingAsIndex("extruder_nr"))->setIsUsed(true);
}
}
//If the machine settings have been supplied, offset the given position vertices to the center of vertices (0,0,0) is at the bed center.
Point3 meshgroup_offset(0, 0, 0);
if (!getSettingBoolean("machine_center_is_zero"))
{
meshgroup_offset.x = getSettingInMicrons("machine_width") / 2;
meshgroup_offset.y = getSettingInMicrons("machine_depth") / 2;
}
// If a mesh position was given, put the mesh at this position in 3D space.
for(Mesh& mesh : meshes)
{
Point3 mesh_offset(mesh.getSettingInMicrons("mesh_position_x"), mesh.getSettingInMicrons("mesh_position_y"), mesh.getSettingInMicrons("mesh_position_z"));
if (mesh.getSettingBoolean("center_object"))
{
Point3 object_min = mesh.min();
Point3 object_max = mesh.max();
Point3 object_size = object_max - object_min;
mesh_offset += Point3(-object_min.x - object_size.x / 2, -object_min.y - object_size.y / 2, -object_min.z);
}
mesh.offset(mesh_offset + meshgroup_offset);
}
}
bool loadMeshSTL_ascii(Mesh* mesh, const char* filename, const FMatrix3x3& matrix)
{
FILE* f = fopen(filename, "rt");
char buffer[1024];
FPoint3 vertex;
int n = 0;
Point3 v0(0,0,0), v1(0,0,0), v2(0,0,0);
while(fgets_(buffer, sizeof(buffer), f))
{
if (sscanf(buffer, " vertex %f %f %f", &vertex.x, &vertex.y, &vertex.z) == 3)
{
n++;
switch(n)
{
case 1:
v0 = matrix.apply(vertex);
break;
case 2:
v1 = matrix.apply(vertex);
break;
case 3:
v2 = matrix.apply(vertex);
mesh->addFace(v0, v1, v2);
n = 0;
break;
}
}
}
fclose(f);
mesh->finish();
return true;
}
bool loadMeshSTL_binary(Mesh* mesh, const char* filename, const FMatrix3x3& matrix)
{
FILE* f = fopen(filename, "rb");
fseek(f, 0L, SEEK_END);
long long file_size = ftell(f); //The file size is the position of the cursor after seeking to the end.
rewind(f); //Seek back to start.
size_t face_count = (file_size - 80 - sizeof(uint32_t)) / 50; //Subtract the size of the header. Every face uses exactly 50 bytes.
char buffer[80];
//Skip the header
if (fread(buffer, 80, 1, f) != 1)
{
fclose(f);
return false;
}
uint32_t reported_face_count;
//Read the face count. We'll use it as a sort of redundancy code to check for file corruption.
if (fread(&reported_face_count, sizeof(uint32_t), 1, f) != 1)
{
fclose(f);
return false;
}
if (reported_face_count != face_count)
{
logWarning("Face count reported by file (%s) is not equal to actual face count (%s). File could be corrupt!\n", std::to_string(reported_face_count).c_str(), std::to_string(face_count).c_str());
}
//For each face read:
//float(x,y,z) = normal, float(X,Y,Z)*3 = vertexes, uint16_t = flags
// Every Face is 50 Bytes: Normal(3*float), Vertices(9*float), 2 Bytes Spacer
mesh->faces.reserve(face_count);
mesh->vertices.reserve(face_count);
for (unsigned int i = 0; i < face_count; i++)
{
if (fread(buffer, 50, 1, f) != 1)
{
fclose(f);
return false;
}
float *v= ((float*)buffer)+3;
Point3 v0 = matrix.apply(FPoint3(v[0], v[1], v[2]));
Point3 v1 = matrix.apply(FPoint3(v[3], v[4], v[5]));
Point3 v2 = matrix.apply(FPoint3(v[6], v[7], v[8]));
mesh->addFace(v0, v1, v2);
}
fclose(f);
mesh->finish();
return true;
}
bool loadMeshSTL(Mesh* mesh, const char* filename, const FMatrix3x3& matrix)
{
FILE* f = fopen(filename, "r");
if (f == nullptr)
{
return false;
}
//Skip any whitespace at the beginning of the file.
unsigned long long num_whitespace = 0; //Number of whitespace characters.
unsigned char whitespace;
if (fread(&whitespace, 1, 1, f) != 1)
{
fclose(f);
return false;
}
while(isspace(whitespace))
{
num_whitespace++;
if (fread(&whitespace, 1, 1, f) != 1)
{
fclose(f);
return false;
}
}
fseek(f, num_whitespace, SEEK_SET); //Seek to the place after all whitespace (we may have just read too far).
char buffer[6];
if (fread(buffer, 5, 1, f) != 1)
{
fclose(f);
return false;
}
fclose(f);
buffer[5] = '\0';
if (stringcasecompare(buffer, "solid") == 0)
{
bool load_success = loadMeshSTL_ascii(mesh, filename, matrix);
if (!load_success)
return false;
// This logic is used to handle the case where the file starts with
// "solid" but is a binary file.
if (mesh->faces.size() < 1)
{
mesh->clear();
return loadMeshSTL_binary(mesh, filename, matrix);
}
return true;
}
return loadMeshSTL_binary(mesh, filename, matrix);
}
bool loadMeshIntoMeshGroup(MeshGroup* meshgroup, const char* filename, const FMatrix3x3& transformation, SettingsBaseVirtual* object_parent_settings)
{
TimeKeeper load_timer;
const char* ext = strrchr(filename, '.');
if (ext && (strcmp(ext, ".stl") == 0 || strcmp(ext, ".STL") == 0))
{
Mesh mesh = object_parent_settings ? Mesh(object_parent_settings) : Mesh(meshgroup); //If we have object_parent_settings, use them as parent settings. Otherwise, just use meshgroup.
if(loadMeshSTL(&mesh,filename,transformation)) //Load it! If successful...
{
meshgroup->meshes.push_back(mesh);
log("loading '%s' took %.3f seconds\n",filename,load_timer.restart());
return true;
}
}
return false;
}
}//namespace cura
+60
Ver Arquivo
@@ -0,0 +1,60 @@
/** Copyright (C) 2013 David Braam - Released under terms of the AGPLv3 License */
#ifndef MESH_GROUP_H
#define MESH_GROUP_H
#include "utils/NoCopy.h"
#include "mesh.h"
#include "ExtruderTrain.h"
namespace cura
{
/*!
* A MeshGroup is a collection with 1 or more 3D meshes.
*
* One MeshGroup is a whole which is printed at once.
* Generally there is one single MeshGroup, though when using one-at-a-time printing, multiple MeshGroups are processed consecutively.
*/
class MeshGroup : public SettingsBase, NoCopy
{
ExtruderTrain* extruders[MAX_EXTRUDERS] = {nullptr};
mutable int extruder_count; //!< The number of extruders. (mutable because of lazy evaluation)
public:
int getExtruderCount() const;
MeshGroup(SettingsBaseVirtual* settings_base);
~MeshGroup();
/*!
* Create a new extruder train for the @p extruder_nr, or return the one which already exists.
*/
ExtruderTrain* createExtruderTrain(unsigned int extruder_nr);
ExtruderTrain* getExtruderTrain(unsigned int extruder_nr);
const ExtruderTrain* getExtruderTrain(unsigned int extruder_nr) const;
std::vector<Mesh> meshes;
Point3 min() const; //! minimal corner of bounding box
Point3 max() const; //! maximal corner of bounding box
void clear();
void finalize();
};
/*!
* Load a Mesh from file and store it in the \p meshgroup.
*
* \param meshgroup The meshgroup where to store the mesh
* \param filename The filename of the mesh file
* \param transformation The transformation applied to all vertices
* \param object_parent_settings (optional) The parent settings object of the new mesh. Defaults to \p meshgroup if none is given.
* \return whether the file could be loaded
*/
bool loadMeshIntoMeshGroup(MeshGroup* meshgroup, const char* filename, const FMatrix3x3& transformation, SettingsBaseVirtual* object_parent_settings = nullptr);
}//namespace cura
#endif//MESH_GROUP_H
+195
Ver Arquivo
@@ -0,0 +1,195 @@
#include "Preheat.h"
namespace cura
{
void Preheat::setConfig(const MeshGroup& meshgroup)
{
for (int extruder_nr = 0; extruder_nr < meshgroup.getExtruderCount(); extruder_nr++)
{
assert(meshgroup.getExtruderTrain(extruder_nr) != nullptr);
const ExtruderTrain& extruder_train = *meshgroup.getExtruderTrain(extruder_nr);
config_per_extruder.emplace_back();
Config& config = config_per_extruder.back();
double machine_nozzle_cool_down_speed = extruder_train.getSettingInSeconds("machine_nozzle_cool_down_speed");
double machine_nozzle_heat_up_speed = extruder_train.getSettingInSeconds("machine_nozzle_heat_up_speed");
double material_extrusion_cool_down_speed = extruder_train.getSettingInSeconds("material_extrusion_cool_down_speed");
assert(material_extrusion_cool_down_speed < machine_nozzle_heat_up_speed && "The extrusion cooldown speed must be smaller than the heat up speed; otherwise the printing temperature cannot be reached!");
config.time_to_cooldown_1_degree[0] = 1.0 / machine_nozzle_cool_down_speed;
config.time_to_heatup_1_degree[0] = 1.0 / machine_nozzle_heat_up_speed;
config.time_to_cooldown_1_degree[1] = 1.0 / (machine_nozzle_cool_down_speed + material_extrusion_cool_down_speed);
config.time_to_heatup_1_degree[1] = 1.0 / (machine_nozzle_heat_up_speed - material_extrusion_cool_down_speed);
config.standby_temp = extruder_train.getSettingInSeconds("material_standby_temperature");
config.min_time_window = extruder_train.getSettingInSeconds("machine_min_cool_heat_time_window");
config.material_print_temperature = extruder_train.getSettingInDegreeCelsius("material_print_temperature");
config.material_print_temperature_layer_0 = extruder_train.getSettingInDegreeCelsius("material_print_temperature_layer_0");
config.material_initial_print_temperature = extruder_train.getSettingInDegreeCelsius("material_initial_print_temperature");
config.material_final_print_temperature = extruder_train.getSettingInDegreeCelsius("material_final_print_temperature");
config.flow_dependent_temperature = extruder_train.getSettingBoolean("material_flow_dependent_temperature");
config.flow_temp_graph = extruder_train.getSettingAsFlowTempGraph("material_flow_temp_graph"); // [[0.1,180],[20,230]]
}
}
double Preheat::getTimeToGoFromTempToTemp(int extruder, double temp_before, double temp_after, bool during_printing)
{
Config& config = config_per_extruder[extruder];
double time;
if (temp_after > temp_before)
{
time = (temp_after - temp_before) * config.time_to_heatup_1_degree[during_printing];
}
else
{
time = (temp_before - temp_after) * config.time_to_cooldown_1_degree[during_printing];
}
return std::max(0.0, time);
}
double Preheat::getTemp(unsigned int extruder, double flow, bool is_initial_layer)
{
if (is_initial_layer && config_per_extruder[extruder].material_print_temperature_layer_0 != 0)
{
return config_per_extruder[extruder].material_print_temperature_layer_0;
}
return config_per_extruder[extruder].flow_temp_graph.getTemp(flow, config_per_extruder[extruder].material_print_temperature, config_per_extruder[extruder].flow_dependent_temperature);
}
Preheat::WarmUpResult Preheat::getWarmUpPointAfterCoolDown(double time_window, unsigned int extruder, double temp_start, double temp_mid, double temp_end, bool during_printing)
{
WarmUpResult result;
const Config& config = config_per_extruder[extruder];
double time_to_cooldown_1_degree = config.time_to_cooldown_1_degree[during_printing];
double time_to_heatup_1_degree = config.time_to_heatup_1_degree[during_printing];
result.total_time_window = time_window;
// ,temp_end
// / .
// ,temp_start / .
// \ ' ' ' ' '/ ' ' '> outer_temp .
// \________/ .
// "-> temp_mid
// ^^^^^^^^^^
// limited_time_window
double outer_temp;
double limited_time_window;
if (temp_start < temp_end)
{ // extra time needed during heating
double extra_heatup_time = (temp_end - temp_start) * time_to_heatup_1_degree;
result.heating_time = extra_heatup_time;
limited_time_window = time_window - extra_heatup_time;
outer_temp = temp_start;
if (limited_time_window < 0.0)
{
result.heating_time = 0.0;
result.lowest_temperature = temp_start;
return result;
}
}
else
{
double extra_cooldown_time = (temp_start - temp_end) * time_to_cooldown_1_degree;
result.heating_time = 0;
limited_time_window = time_window - extra_cooldown_time;
outer_temp = temp_end;
if (limited_time_window < 0.0)
{
result.heating_time = 0.0;
result.lowest_temperature = temp_end;
return result;
}
}
double time_ratio_cooldown_heatup = time_to_cooldown_1_degree / time_to_heatup_1_degree;
double time_to_heat_from_standby_to_print_temp = getTimeToGoFromTempToTemp(extruder, temp_mid, outer_temp, during_printing);
double time_needed_to_reach_standby_temp = time_to_heat_from_standby_to_print_temp * (1.0 + time_ratio_cooldown_heatup);
if (time_needed_to_reach_standby_temp < limited_time_window)
{
result.heating_time += time_to_heat_from_standby_to_print_temp;
result.lowest_temperature = temp_mid;
}
else
{
result.heating_time += limited_time_window * time_to_heatup_1_degree / (time_to_cooldown_1_degree + time_to_heatup_1_degree);
result.lowest_temperature = std::max(temp_mid, temp_end - result.heating_time / time_to_heatup_1_degree);
}
if (result.heating_time > time_window || result.heating_time < 0.0)
{
logWarning("getWarmUpPointAfterCoolDown returns result outside of the time window!");
}
return result;
}
Preheat::CoolDownResult Preheat::getCoolDownPointAfterWarmUp(double time_window, unsigned int extruder, double temp_start, double temp_mid, double temp_end, bool during_printing)
{
CoolDownResult result;
const Config& config = config_per_extruder[extruder];
double time_to_cooldown_1_degree = config.time_to_cooldown_1_degree[during_printing];
double time_to_heatup_1_degree = config.time_to_heatup_1_degree[during_printing];
assert(temp_start != -1 && temp_mid != -1 && temp_end != -1 && "temperatures must be initialized!");
result.total_time_window = time_window;
// limited_time_window
// :^^^^^^^^^^^^:
// : ________. : . . .> temp_mid
// : / \ : .
// :/ . . . . .\:. . .> outer_temp .
// ^temp_start \ .
// \ .
// ^temp_end
double outer_temp;
double limited_time_window;
if (temp_start < temp_end)
{ // extra time needed during heating
double extra_heatup_time = (temp_end - temp_start) * time_to_heatup_1_degree;
result.cooling_time = 0;
limited_time_window = time_window - extra_heatup_time;
outer_temp = temp_end;
if (limited_time_window < 0.0)
{
result.cooling_time = 0.0;
result.highest_temperature = temp_end;
return result;
}
}
else
{
double extra_cooldown_time = (temp_start - temp_end) * time_to_cooldown_1_degree;
result.cooling_time = extra_cooldown_time;
limited_time_window = time_window - extra_cooldown_time;
outer_temp = temp_start;
if (limited_time_window < 0.0)
{
result.cooling_time = 0.0;
result.highest_temperature = temp_start;
return result;
}
}
double time_ratio_cooldown_heatup = time_to_cooldown_1_degree / time_to_heatup_1_degree;
double cool_down_time = getTimeToGoFromTempToTemp(extruder, temp_mid, outer_temp, during_printing);
double time_needed_to_reach_temp1 = cool_down_time * (1.0 + time_ratio_cooldown_heatup);
if (time_needed_to_reach_temp1 < limited_time_window)
{
result.cooling_time += cool_down_time;
result.highest_temperature = temp_mid;
}
else
{
result.cooling_time += limited_time_window * time_to_heatup_1_degree / (time_to_cooldown_1_degree + time_to_heatup_1_degree);
result.highest_temperature = std::min(temp_mid, temp_end + result.cooling_time / time_to_cooldown_1_degree);
}
if (result.cooling_time > time_window || result.cooling_time < 0.0)
{
logWarning("getCoolDownPointAfterWarmUp returns result outside of the time window!");
}
return result;
}
}//namespace cura
+203
Ver Arquivo
@@ -0,0 +1,203 @@
#ifndef PREHEAT_H
#define PREHEAT_H
#include <cassert>
#include <algorithm> // max
#include "utils/logoutput.h"
#include "MeshGroup.h"
#include "FlowTempGraph.h"
namespace cura
{
/*!
* Class for computing heatup and cooldown times used for computing the time the printer needs to heat up to a printing temperature.
*/
class Preheat
{
/*!
* The nozzle and material temperature settings for an extruder train.
*/
class Config
{
public:
double time_to_heatup_1_degree[2]; //!< average time it takes to heat up one degree (in the range of normal print temperatures and standby temperature), while not-printing and while printing
double time_to_cooldown_1_degree[2]; //!< average time it takes to cool down one degree (in the range of normal print temperatures and standby temperature), while not-printing and while printing
double standby_temp; //!< The temperature at which the nozzle rests when it is not printing.
double min_time_window; //!< Minimal time (in seconds) to allow an extruder to cool down and then warm up again.
double material_print_temperature; //!< default print temp (backward compatilibily)
double material_print_temperature_layer_0; //!< initial layer print temp
double material_initial_print_temperature; //!< print temp when first starting to extrude after a layer switch
double material_final_print_temperature; //!< print temp at the end of all extrusion moves of an extruder to which it's cooled down just before - during the extrusion
bool flow_dependent_temperature; //!< Whether to make the temperature dependent on flow
FlowTempGraph flow_temp_graph; //!< The graph linking flows to corresponding temperatures
};
std::vector<Config> config_per_extruder;//!< the nozzle and material temperature settings for each extruder train.
public:
/*!
* The type of result when computing when to start heating up a nozzle before it's going to be used again.
*/
struct WarmUpResult
{
double total_time_window; //!< The total time in which cooling and heating takes place.
double heating_time; //!< The total time needed to heat to the required temperature.
double lowest_temperature; //!< The lower temperature from which heating starts.
};
/*!
* The type of result when computing when to start cooling down a nozzle before it's not going to be used again.
*/
struct CoolDownResult
{
double total_time_window; //!< The total time in which heating and cooling takes place.
double cooling_time; //!< The total time needed to cool down to the required temperature.
double highest_temperature; //!< The upper temperature from which cooling starts.
};
/*!
* Get the standby temperature of an extruder train
* \param extruder the extruder train for which to get the standby tmep
* \return the standby temp
*/
double getStandbyTemp(int extruder)
{
return config_per_extruder[extruder].standby_temp;
}
/*!
* Get the time it takes to heat up one degree celsius
*
* \param extruder the extruder train for which to get time it takes to heat up one degree celsius
* \param during_printing whether the heating takes time during printing or when idle
* \return the time it takes to heat up one degree celsius
*/
double getTimeToHeatup1Degree(int extruder, bool during_printing)
{
return config_per_extruder[extruder].time_to_heatup_1_degree[during_printing];
}
/*!
* Get the initial print temperature when starting to extrude.
* \param during_printing whether the heating takes time during printing or when idle
*/
double getInitialPrintTemp(int extruder)
{
return config_per_extruder[extruder].material_initial_print_temperature;
}
/*!
* Get the final print temperature at the end of all extrusion moves with the current extruder
*/
double getFinalPrintTemp(int extruder)
{
return config_per_extruder[extruder].material_final_print_temperature;
}
/*!
* Set the nozzle and material temperature settings for each extruder train.
* \param meshgroup Where to get settings from
*/
void setConfig(const MeshGroup& meshgroup);
bool usesFlowDependentTemp(int extruder_nr)
{
return config_per_extruder[extruder_nr].flow_dependent_temperature;
}
public:
/*!
* Get the optimal temperature corresponding to a given average flow,
* or the initial layer temperature.
*
* \param extruder The extruder train
* \param flow The flow for which to get the optimal temperature
* \param is_initial_layer Whether the initial layer temperature should be returned instead of flow-based temperature
* \return The corresponding optimal temperature
*/
double getTemp(unsigned int extruder, double flow, bool is_initial_layer);
/*!
* Return the minimal time window of a specific extruder for letting an unused extruder cool down and warm up again
* \param extruder The extruder for which to get the minimal time window
* \return the minimal time window of a specific extruder for letting an unused extruder cool down and warm up again
*/
double getMinimalTimeWindow(unsigned int extruder)
{
return config_per_extruder[extruder].min_time_window;
}
/*!
* Decide when to start warming up again after starting to cool down towards \p temp_mid.
* Two cases are considered:
* the case where the standby temperature is reached \__/ .
* and the case where it isn't \/ .
*
* \warning it is assumed that \p temp_mid is lower than both \p temp_start and \p temp_end. If not somewhat weird results may follow.
*
// ,temp_end
// / .
// ,temp_start / .
// \ / .
// \________/ .
// "-> temp_mid
* \param window_time The time window within which the cooldown and heat up must take place.
* \param extruder The extruder used
* \param temp_start The temperature from which to start cooling down
* \param temp_mid The temeprature to which we try to cool down
* \param temp_end The temperature to which we need to have heated up at the end of the \p time_window
* \param during_printing Whether the warming up and cooling down is performed during printing
* \return The time before the end of the @p time_window to insert the preheat command and the temperature from which the heating starts
*/
WarmUpResult getWarmUpPointAfterCoolDown(double time_window, unsigned int extruder, double temp_start, double temp_mid, double temp_end, bool during_printing);
/*!
* Decide when to start cooling down again after starting to warm up towards the \p temp_mid
* Two cases are considered:
* the case where the temperature is reached /"""\ .
* and the case where it isn't /\ .
*
* \warning it is assumed that \p temp_mid is higher than both \p temp_start and \p temp_end. If not somewhat weird results may follow.
*
// _> temp_mid
// /""""""""\ .
// / \ .
// ^temp_start \ .
// \ .
// ^temp_end
* \param window_time The time window within which the cooldown and heat up must take place.
* \param extruder The extruder used
* \param temp_start The temperature from which to start heating up
* \param temp_mid The temeprature to which we try to heat up
* \param temp_end The temperature to which we need to have cooled down after \p time_window time
* \param during_printing Whether the warming up and cooling down is performed during printing
* \return The time before the end of the \p time_window to insert the preheat command and the temperature from which the cooling starts
*/
CoolDownResult getCoolDownPointAfterWarmUp(double time_window, unsigned int extruder, double temp_start, double temp_mid, double temp_end, bool during_printing);
/*!
* Get the time to go from one temperature to another temperature
* \param extruder The extruder number for which to perform the heatup / cooldown
* \param temp_before The before temperature
* \param temp_after The after temperature
* \param during_printing Whether the planned cooldown / warmup occurs during printing or while in standby mode
* \return The time needed
*/
double getTimeToGoFromTempToTemp(int extruder, double temp_before, double temp_after, bool during_printing);
};
} // namespace cura
#endif // PREHEAT_H
+299
Ver Arquivo
@@ -0,0 +1,299 @@
#include "PrimeTower.h"
#include <limits>
#include "ExtruderTrain.h"
#include "sliceDataStorage.h"
#include "gcodeExport.h"
#include "gcodePlanner.h"
#include "infill.h"
#include "PrintFeature.h"
namespace cura
{
PrimeTower::PrimeTower()
: is_hollow(false)
, wipe_from_middle(false)
, current_pre_wipe_location_idx(0)
{
for (int extruder_nr = 0; extruder_nr < MAX_EXTRUDERS; extruder_nr++)
{
last_prime_tower_poly_printed[extruder_nr] = -1;
}
}
void PrimeTower::initConfigs(const MeshGroup* meshgroup)
{
extruder_count = meshgroup->getExtruderCount();
for (int extr = 0; extr < extruder_count; extr++)
{
config_per_extruder.emplace_back(PrintFeatureType::Support);// so that visualization in the old Cura still works (TODO)
}
for (int extr = 0; extr < extruder_count; extr++)
{
const ExtruderTrain* train = meshgroup->getExtruderTrain(extr);
config_per_extruder[extr].init(train->getSettingInMillimetersPerSecond("speed_prime_tower"), train->getSettingInMillimetersPerSecond("acceleration_prime_tower"), train->getSettingInMillimetersPerSecond("jerk_prime_tower"), train->getSettingInMicrons("prime_tower_line_width"), train->getSettingInPercentage("prime_tower_flow"));
}
}
void PrimeTower::setConfigs(const MeshGroup* meshgroup, const int layer_thickness)
{
extruder_count = meshgroup->getExtruderCount();
for (int extr = 0; extr < extruder_count; extr++)
{
GCodePathConfig& conf = config_per_extruder[extr];
conf.setLayerHeight(layer_thickness);
}
}
void PrimeTower::generateGroundpoly(const SliceDataStorage& storage)
{
extruder_count = storage.meshgroup->getExtruderCount();
int64_t prime_tower_wall_thickness = storage.getSettingInMicrons("prime_tower_wall_thickness");
int64_t tower_size = storage.getSettingInMicrons("prime_tower_size");
if (prime_tower_wall_thickness * 2 < tower_size)
{
is_hollow = true;
}
PolygonRef p = ground_poly.newPoly();
int tower_distance = 0;
int x = storage.getSettingInMicrons("prime_tower_position_x"); // storage.model_max.x
int y = storage.getSettingInMicrons("prime_tower_position_y"); // storage.model_max.y
p.add(Point(x + tower_distance, y + tower_distance));
p.add(Point(x + tower_distance, y + tower_distance + tower_size));
p.add(Point(x + tower_distance - tower_size, y + tower_distance + tower_size));
p.add(Point(x + tower_distance - tower_size, y + tower_distance));
middle = Point(x - tower_size / 2, y + tower_size / 2);
if (is_hollow)
{
ground_poly = ground_poly.difference(ground_poly.offset(-prime_tower_wall_thickness));
}
post_wipe_point = Point(x + tower_distance - tower_size / 2, y + tower_distance + tower_size / 2);
}
void PrimeTower::generatePaths(const SliceDataStorage& storage)
{
enabled = storage.max_print_height_second_to_last_extruder >= 0
&& storage.getSettingBoolean("prime_tower_enable")
&& storage.getSettingInMicrons("prime_tower_wall_thickness") > 10
&& storage.getSettingInMicrons("prime_tower_size") > 10;
if (enabled)
{
generatePaths_denseInfill(storage);
generateWipeLocations(storage);
}
}
void PrimeTower::generatePaths_denseInfill(const SliceDataStorage& storage)
{
int n_patterns = 2; // alternating patterns between layers
int infill_overlap = 60; // so that it can't be zero; EDIT: wtf?
int extra_infill_shift = 0;
generateGroundpoly(storage);
int64_t z = 0; // (TODO) because the prime tower stores the paths for each extruder for once instead of generating each layer, we don't know the z position
for (int extruder = 0; extruder < extruder_count; extruder++)
{
int line_width = storage.meshgroup->getExtruderTrain(extruder)->getSettingInMicrons("prime_tower_line_width");
patterns_per_extruder.emplace_back(n_patterns);
std::vector<ExtrusionMoves>& patterns = patterns_per_extruder.back();
patterns.resize(n_patterns);
for (int pattern_idx = 0; pattern_idx < n_patterns; pattern_idx++)
{
patterns[pattern_idx].polygons = ground_poly.offset(-line_width / 2);
Polygons& result_lines = patterns[pattern_idx].lines;
int outline_offset = -line_width;
int line_distance = line_width;
double fill_angle = 45 + pattern_idx * 90;
Polygons result_polygons; // should remain empty, since we generate lines pattern!
Infill infill_comp(EFillMethod::LINES, ground_poly, outline_offset, line_width, line_distance, infill_overlap, fill_angle, z, extra_infill_shift);
infill_comp.generate(result_polygons, result_lines);
}
}
}
void PrimeTower::addToGcode(const SliceDataStorage& storage, GCodePlanner& gcodeLayer, const GCodeExport& gcode, const int layer_nr, const int prev_extruder, const int new_extruder)
{
if (!enabled)
{
return;
}
bool prime_tower_added = false;
for (int extruder = 0; extruder < storage.meshgroup->getExtruderCount() && !prime_tower_added; extruder++)
{
prime_tower_added = last_prime_tower_poly_printed[extruder] == int(layer_nr);
}
if (prime_tower_added)
{ // don't print the prime tower if it has been printed already
return;
}
if (layer_nr > storage.max_print_height_second_to_last_extruder + 1)
{
return;
}
bool pre_wipe = storage.meshgroup->getExtruderTrain(new_extruder)->getSettingBoolean("dual_pre_wipe");
bool post_wipe = storage.meshgroup->getExtruderTrain(prev_extruder)->getSettingBoolean("prime_tower_wipe_enabled");
if (prev_extruder == new_extruder)
{
pre_wipe = false;
post_wipe = false;
}
// pre-wipe:
if (pre_wipe)
{
preWipe(storage, gcodeLayer, new_extruder);
}
addToGcode_denseInfill(storage, gcodeLayer, gcode, layer_nr, prev_extruder, new_extruder);
// post-wipe:
if (post_wipe)
{ //Make sure we wipe the old extruder on the prime tower.
gcodeLayer.addTravel(post_wipe_point - gcode.getExtruderOffset(prev_extruder) + gcode.getExtruderOffset(new_extruder));
}
}
void PrimeTower::addToGcode_denseInfill(const SliceDataStorage& storage, GCodePlanner& gcodeLayer, const GCodeExport& gcode, const int layer_nr, const int prev_extruder, const int new_extruder)
{
ExtrusionMoves& pattern = patterns_per_extruder[new_extruder][((layer_nr % 2) + 2) % 2]; // +2) %2 to handle negative layer numbers
GCodePathConfig& config = config_per_extruder[new_extruder];
gcodeLayer.addPolygonsByOptimizer(pattern.polygons, &config);
gcodeLayer.addLinesByOptimizer(pattern.lines, &config, SpaceFillType::Lines);
last_prime_tower_poly_printed[new_extruder] = layer_nr;
}
Point PrimeTower::getLocationBeforePrimeTower(const SliceDataStorage& storage)
{
Point ret(0, 0);
int absolute_starting_points = 0;
for (int extruder_nr = 0; extruder_nr < storage.meshgroup->getExtruderCount(); extruder_nr++)
{
ExtruderTrain& train = *storage.meshgroup->getExtruderTrain(0);
if (train.getSettingBoolean("machine_extruder_start_pos_abs"))
{
ret += Point(train.getSettingInMicrons("machine_extruder_start_pos_x"), train.getSettingInMicrons("machine_extruder_start_pos_y"));
absolute_starting_points++;
}
}
if (absolute_starting_points > 0)
{ // take the average over all absolute starting positions
ret /= absolute_starting_points;
}
else
{ // use the middle of the bed
if (!storage.getSettingBoolean("machine_center_is_zero"))
{
ret = Point(storage.getSettingInMicrons("machine_width"), storage.getSettingInMicrons("machine_depth")) / 2;
}
// otherwise keep (0, 0)
}
return ret;
}
void PrimeTower::generateWipeLocations(const SliceDataStorage& storage)
{
wipe_from_middle = is_hollow;
// only wipe from the middle of the prime tower if we have a z hop already on the first move after the layer switch
for (int extruder_nr = 0; extruder_nr < storage.meshgroup->getExtruderCount(); extruder_nr++)
{
const ExtruderTrain& train = *storage.meshgroup->getExtruderTrain(extruder_nr);
wipe_from_middle &= train.getSettingBoolean("retraction_hop_enabled")
&& (!train.getSettingBoolean("retraction_hop_only_when_collides") || train.getSettingBoolean("retraction_hop_after_extruder_switch"));
}
PolygonsPointIndex segment_start; // from where to start the sequence of wipe points
PolygonsPointIndex segment_end; // where to end the sequence of wipe points
if (wipe_from_middle)
{
// take the same start as end point so that the whole poly os covered.
// find the inner polygon.
segment_start = segment_end = PolygonUtils::findNearestVert(middle, ground_poly);
}
else
{
// take the closer corner of the wipe tower and generate wipe locations on that side only:
//
// |
// |
// +-----
// .
// ^ nozzle switch location
Point from = getLocationBeforePrimeTower(storage);
// find the single line segment closest to [from] pointing most toward [from]
PolygonsPointIndex closest_vert = PolygonUtils::findNearestVert(from, ground_poly);
PolygonsPointIndex prev = closest_vert.prev();
PolygonsPointIndex next = closest_vert.next();
int64_t prev_dot_score = dot(from - closest_vert.p(), turn90CCW(prev.p() - closest_vert.p()));
int64_t next_dot_score = dot(from - closest_vert.p(), turn90CCW(closest_vert.p() - next.p()));
if (prev_dot_score > next_dot_score)
{
segment_start = prev;
segment_end = closest_vert;
}
else
{
segment_start = closest_vert;
segment_end = next;
}
}
PolygonUtils::spreadDots(segment_start, segment_end, number_of_pre_wipe_locations, pre_wipe_locations);
}
void PrimeTower::preWipe(const SliceDataStorage& storage, GCodePlanner& gcode_layer, const int extruder_nr)
{
const ClosestPolygonPoint wipe_location = pre_wipe_locations[current_pre_wipe_location_idx];
current_pre_wipe_location_idx = (current_pre_wipe_location_idx + pre_wipe_location_skip) % number_of_pre_wipe_locations;
ExtruderTrain& train = *storage.meshgroup->getExtruderTrain(extruder_nr);
const int inward_dist = train.getSettingInMicrons("machine_nozzle_size") * 3 / 2 ;
const int start_dist = train.getSettingInMicrons("machine_nozzle_size") * 2;
const Point end = PolygonUtils::moveInsideDiagonally(wipe_location, inward_dist);
const Point outward_dir = wipe_location.location - end;
const Point start = wipe_location.location + normal(outward_dir, start_dist);
if (wipe_from_middle)
{
// for hollow wipe tower:
// start from above
// go to wipe start
// go to the Z height of the previous/current layer
// wipe
// go to normal layer height (automatically on the next extrusion move)...
GCodePath& toward_middle = gcode_layer.addTravel(middle);
toward_middle.perform_z_hop = true;
gcode_layer.forceNewPathStart();
GCodePath& toward_wipe_start = gcode_layer.addTravel_simple(start);
toward_wipe_start.perform_z_hop = false;
toward_wipe_start.retract = true;
}
else
{
gcode_layer.addTravel(start);
}
float flow = 0.0001; // force this path being interpreted as an extrusion path, so that no Z hop will occur (TODO: really separately handle travel and extrusion moves)
gcode_layer.addExtrusionMove(end, &config_per_extruder[extruder_nr], SpaceFillType::None, flow);
}
}//namespace cura
+163
Ver Arquivo
@@ -0,0 +1,163 @@
#ifndef PRIME_TOWER_H
#define PRIME_TOWER_H
#include <vector>
#include "GCodePathConfig.h"
#include "MeshGroup.h"
#include "utils/polygon.h" // Polygons
#include "utils/polygonUtils.h"
namespace cura
{
class SliceDataStorage;
class GCodePlanner;
class GCodeExport;
/*!
* Class for everything to do with the prime tower:
* - generating the areas
* - checking up till which height the prime tower has to be printed
* - generating the paths and adding them to the layer plan
*/
class PrimeTower
{
private:
struct ExtrusionMoves
{
Polygons polygons;
Polygons lines;
};
bool enabled; //!< Whether the prime tower is enabled
int extruder_count; //!< number of extruders
std::vector<GCodePathConfig> config_per_extruder; //!< Path config for prime tower for each extruder
bool is_hollow; //!< Whether the prime tower is hollow
bool wipe_from_middle; //!< Whether to wipe on the inside of the hollow prime tower
Point middle; //!< The middle of the prime tower
Point post_wipe_point; //!< location to post-wipe the unused nozzle off on
std::vector<ClosestPolygonPoint> pre_wipe_locations; //!< The differernt locations where to pre-wipe the active nozzle
const unsigned int pre_wipe_location_skip = 13; //!< How big the steps are when stepping through \ref PrimeTower::wipe_locations
const unsigned int number_of_pre_wipe_locations = 21; //!< The required size of \ref PrimeTower::wipe_locations
// note that the above are two consecutive numbers in the Fibonacci sequence
int current_pre_wipe_location_idx; //!< Index into \ref PrimeTower::wipe_locations of where to pre-wipe the nozzle
public:
Polygons ground_poly; //!< The outline of the prime tower to be used for each layer
std::vector<std::vector<ExtrusionMoves>> patterns_per_extruder; //!< for each extruder a vector of patterns to alternate between, over the layers
/*!
* Initialize \ref PrimeTower::config_per_extruder with speed and line width settings.
*
* \param meshgroup Where to retrieve the setttings for each extruder
*/
void initConfigs(const MeshGroup* meshgroup);
/*!
* Complete the \ref PrimeTower::config_per_extruder by settings the layer height.
*
* \param meshgroup Where to retrieve the setttings for each extruder
* \param layer_thickness The current layer thickness
*/
void setConfigs(const MeshGroup* meshgroup, const int layer_thickness);
/*!
* Generate the prime tower area to be used on each layer
*
* Fills \ref PrimeTower::ground_poly and sets \ref PrimeTower::middle
*
* \param storage Where to retrieve prime tower settings from
*/
void generateGroundpoly(const SliceDataStorage& storage);
/*!
* Generate the area where the prime tower should be.
*
* \param storage where to get settings from
* \param total_layers The total number of layers
*/
void generatePaths(const SliceDataStorage& storage);
PrimeTower(); //!< basic constructor
/*!
* Add path plans for the prime tower to the \p gcode_layer
*
* \param storage where to get settings from; where to get the maximum height of the prime tower from
* \param[in,out] gcode_layer Where to get the current extruder from; where to store the generated layer paths
* \param layer_nr The layer for which to generate the prime tower paths
* \param prev_extruder The previous extruder with which paths were planned; from which extruder a switch was made
* \param new_extruder The switched to extruder with which the prime tower paths should be generated.
*/
void addToGcode(const SliceDataStorage& storage, GCodePlanner& gcode_layer, const GCodeExport& gcode, const int layer_nr, const int prev_extruder, const int new_extruder);
private:
/*!
* Layer number of the last layer in which a prime tower has been printed per extruder train.
*
* This is recorded per extruder to account for a prime tower per extruder, instead of the mixed prime tower.
*/
int last_prime_tower_poly_printed[MAX_EXTRUDERS];
/*!
* Find an approriate representation for the point representing the location before going to the prime tower
*
* \warning This is not the actual position each time before the wipe tower
*
* \param storage where to get settings from
* \return that location
*/
Point getLocationBeforePrimeTower(const SliceDataStorage& storage);
/*!
* \param storage where to get settings from
* Depends on ground_poly being generated
*/
void generateWipeLocations(const SliceDataStorage& storage);
/*!
* \see WipeTower::generatePaths
*
* Generate the extrude paths for each extruder on even and odd layers
* Fill the ground poly with dense infill.
*
* \param storage where to get settings from
* \param total_layers The total number of layers
*/
void generatePaths_denseInfill(const SliceDataStorage& storage);
/*!
* \see PrimeTower::addToGcode
*
* Add path plans for the prime tower to the \p gcode_layer
*
* \param storage where to get settings from; where to get the maximum height of the prime tower from
* \param[in,out] gcode_layer Where to get the current extruder from; where to store the generated layer paths
* \param layer_nr The layer for which to generate the prime tower paths
* \param prev_extruder The previous extruder with which paths were planned; from which extruder a switch was made
* \param new_extruder The switched to extruder with which the prime tower paths should be generated.
*/
void addToGcode_denseInfill(const SliceDataStorage& storage, GCodePlanner& gcode_layer, const GCodeExport& gcode, const int layer_nr, const int prev_extruder, const int new_extruder);
/*!
* Plan the moves for wiping the current nozzles oozed material before starting to print the prime tower.
*
* \param storage where to get settings from
* \param[out] gcode_layer where to add the planned paths for wiping
* \param extruder_nr The current extruder
*/
void preWipe(const SliceDataStorage& storage, GCodePlanner& gcode_layer, const int extruder_nr);
};
}//namespace cura
#endif // PRIME_TOWER_H
+27
Ver Arquivo
@@ -0,0 +1,27 @@
#ifndef PRINT_FEATURE
#define PRINT_FEATURE
namespace cura
{
enum class PrintFeatureType: unsigned char
{
NoneType, // used to mark unspecified jumps in polygons. libArcus depends on it
OuterWall,
InnerWall,
Skin,
Support,
SkirtBrim,
Infill,
SupportInfill,
MoveCombing,
MoveRetraction,
SupportInterface
};
} // namespace cura
#endif // PRINT_FEATURE
+28
Ver Arquivo
@@ -0,0 +1,28 @@
/** Copyright (C) 2016 Ultimaker - Released under terms of the AGPLv3 License */
#ifndef RETRACTION_CONFIG_H
#define RETRACTION_CONFIG_H
namespace cura
{
/*!
* The retraction configuration used in the GCodePathConfig of each feature (and the travel config)
*/
class RetractionConfig
{
public:
double distance; //!< The distance retracted (in mm)
double speed; //!< The speed with which to retract (in mm/s)
double primeSpeed; //!< the speed with which to unretract (in mm/s)
double prime_volume; //!< the amount of material primed after unretracting (in mm^3)
int zHop; //!< the amount with which to lift the head during a retraction-travel
int retraction_min_travel_distance; //!< Minimal distance traversed to even consider retracting (in micron)
double retraction_extrusion_window; //!< Window of mm extruded filament in which to limit the amount of retractions
int retraction_count_max; //!< The maximum amount of retractions allowed to occur in the RetractionConfig::retraction_extrusion_window
};
}//namespace cura
#endif // RETRACTION_CONFIG_H
+187
Ver Arquivo
@@ -0,0 +1,187 @@
/** Copyright (C) 2013 David Braam - Released under terms of the AGPLv3 License */
#include "SkirtBrim.h"
#include "support.h"
namespace cura
{
void SkirtBrim::getFirstLayerOutline(SliceDataStorage& storage, const unsigned int primary_line_count, const int primary_extruder_skirt_brim_line_width, const bool is_skirt, const bool outside_only, Polygons& first_layer_outline)
{
bool external_only = is_skirt; // whether to include holes or not
const int layer_nr = 0;
if (is_skirt)
{
const bool include_helper_parts = true;
first_layer_outline = storage.getLayerOutlines(layer_nr, include_helper_parts, external_only);
first_layer_outline = first_layer_outline.approxConvexHull();
}
else
{ // add brim underneath support by removing support where there's brim around the model
const bool include_helper_parts = false; // include manually below
first_layer_outline = storage.getLayerOutlines(layer_nr, include_helper_parts, external_only);
Polygons first_layer_empty_holes;
if (outside_only)
{
first_layer_empty_holes = first_layer_outline.getEmptyHoles();
first_layer_outline = first_layer_outline.removeEmptyHoles();
}
if (storage.support.generated && primary_line_count > 0)
{ // remove model-brim from support
// avoid gap in the middle
// V
// +---+ +----+
// |+-+| |+--+|
// || || ||[]|| > expand to fit an extra brim line
// |+-+| |+--+|
// +---+ +----+
Polygons model_brim_covered_area = first_layer_outline.offset(primary_extruder_skirt_brim_line_width * (primary_line_count + primary_line_count % 2), ClipperLib::jtRound); // always leave a gap of an even number of brim lines, so that it fits if it's generating brim from both sides
if (outside_only)
{ // don't remove support within empty holes where no brim is generated.
model_brim_covered_area.add(first_layer_empty_holes);
}
SupportLayer& support_layer = storage.support.supportLayers[0];
support_layer.supportAreas = support_layer.supportAreas.difference(model_brim_covered_area);
first_layer_outline.add(support_layer.supportAreas);
first_layer_outline.add(support_layer.skin);
}
first_layer_outline.add(storage.primeTower.ground_poly); // don't remove parts of the prime tower, but make a brim for it
}
constexpr int join_distance = 20;
first_layer_outline = first_layer_outline.offset(join_distance).offset(-join_distance); // merge adjacent models into single polygon
constexpr int smallest_line_length = 200;
constexpr int largest_error_of_removed_point = 50;
first_layer_outline.simplify(smallest_line_length, largest_error_of_removed_point); // simplify for faster processing of the brim lines
}
int SkirtBrim::generatePrimarySkirtBrimLines(SliceDataStorage& storage, int start_distance, unsigned int primary_line_count, const int primary_extruder_skirt_brim_line_width, const int64_t primary_extruder_minimal_length, const Polygons& first_layer_outline, Polygons& skirt_brim_primary_extruder)
{
int offset_distance = start_distance - primary_extruder_skirt_brim_line_width / 2;
for (unsigned int skirt_brim_number = 0; skirt_brim_number < primary_line_count; skirt_brim_number++)
{
offset_distance += primary_extruder_skirt_brim_line_width;
Polygons outer_skirt_brim_line = first_layer_outline.offset(offset_distance, ClipperLib::jtRound);
//Remove small inner skirt and brim holes. Holes have a negative area, remove anything smaller then 100x extrusion "area"
for (unsigned int n = 0; n < outer_skirt_brim_line.size(); n++)
{
double area = outer_skirt_brim_line[n].area();
if (area < 0 && area > -primary_extruder_skirt_brim_line_width * primary_extruder_skirt_brim_line_width * 100)
{
outer_skirt_brim_line.remove(n--);
}
}
skirt_brim_primary_extruder.add(outer_skirt_brim_line);
int length = skirt_brim_primary_extruder.polygonLength();
if (skirt_brim_number + 1 >= primary_line_count && length > 0 && length < primary_extruder_minimal_length) //Make brim or skirt have more lines when total length is too small.
{
primary_line_count++;
}
}
return offset_distance;
}
void SkirtBrim::generate(SliceDataStorage& storage, int start_distance, unsigned int primary_line_count, bool outside_only)
{
const bool is_skirt = start_distance > 0;
const int adhesion_extruder_nr = storage.getSettingAsIndex("adhesion_extruder_nr");
const ExtruderTrain* adhesion_extruder = storage.meshgroup->getExtruderTrain(adhesion_extruder_nr);
const int primary_extruder_skirt_brim_line_width = adhesion_extruder->getSettingInMicrons("skirt_brim_line_width");
const int64_t primary_extruder_minimal_length = adhesion_extruder->getSettingInMicrons("skirt_brim_minimal_length");
Polygons& skirt_brim_primary_extruder = storage.skirt_brim[adhesion_extruder_nr];
Polygons first_layer_outline;
getFirstLayerOutline(storage, primary_line_count, primary_extruder_skirt_brim_line_width, is_skirt, outside_only, first_layer_outline);
const bool has_ooze_shield = storage.oozeShield.size() > 0 && storage.oozeShield[0].size() > 0;
const bool has_draft_shield = storage.draft_protection_shield.size() > 0;
if (is_skirt && (has_ooze_shield || has_draft_shield))
{ // make sure we don't generate skirt through draft / ooze shield
first_layer_outline = first_layer_outline.offset(start_distance - primary_extruder_skirt_brim_line_width / 2, ClipperLib::jtRound).unionPolygons(storage.draft_protection_shield);
if (has_ooze_shield)
{
first_layer_outline = first_layer_outline.unionPolygons(storage.oozeShield[0]);
}
first_layer_outline = first_layer_outline.approxConvexHull();
start_distance = primary_extruder_skirt_brim_line_width / 2;
}
int offset_distance = generatePrimarySkirtBrimLines(storage, start_distance, primary_line_count, primary_extruder_skirt_brim_line_width, primary_extruder_minimal_length, first_layer_outline, skirt_brim_primary_extruder);
// generate brim for ooze shield and draft shield
if (!is_skirt && (has_ooze_shield || has_draft_shield))
{
// generate areas where to make extra brim for the shields
// avoid gap in the middle
// V
// +---+ +----+
// |+-+| |+--+|
// || || ||[]|| > expand to fit an extra brim line
// |+-+| |+--+|
// +---+ +----+
const int64_t primary_skirt_brim_width = (primary_line_count + primary_line_count % 2) * primary_extruder_skirt_brim_line_width; // always use an even number, because we will fil the area from both sides
Polygons shield_brim;
if (has_ooze_shield)
{
shield_brim = storage.oozeShield[0].difference(storage.oozeShield[0].offset(-primary_skirt_brim_width - primary_extruder_skirt_brim_line_width));
}
if (has_draft_shield)
{
shield_brim = shield_brim.unionPolygons(storage.draft_protection_shield.difference(storage.draft_protection_shield.offset(-primary_skirt_brim_width - primary_extruder_skirt_brim_line_width)));
}
const Polygons outer_primary_brim = first_layer_outline.offset(offset_distance, ClipperLib::jtRound);
shield_brim = shield_brim.difference(outer_primary_brim.offset(primary_extruder_skirt_brim_line_width));
// generate brim within shield_brim
skirt_brim_primary_extruder.add(shield_brim);
while (shield_brim.size() > 0)
{
shield_brim = shield_brim.offset(-primary_extruder_skirt_brim_line_width);
skirt_brim_primary_extruder.add(shield_brim);
}
// update parameters to generate secondary skirt around
first_layer_outline = outer_primary_brim;
if (has_draft_shield)
{
first_layer_outline = first_layer_outline.unionPolygons(storage.draft_protection_shield);
}
if (has_ooze_shield)
{
first_layer_outline = first_layer_outline.unionPolygons(storage.oozeShield[0]);
}
offset_distance = 0;
}
{ // process other extruders' brim/skirt (as one brim line around the old brim)
int last_width = primary_extruder_skirt_brim_line_width;
for (int extruder = 0; extruder < storage.meshgroup->getExtruderCount(); extruder++)
{
if (extruder == adhesion_extruder_nr || !storage.meshgroup->getExtruderTrain(extruder)->getIsUsed())
{
continue;
}
const ExtruderTrain* train = storage.meshgroup->getExtruderTrain(extruder);
const int width = train->getSettingInMicrons("skirt_brim_line_width");
const int64_t minimal_length = train->getSettingInMicrons("skirt_brim_minimal_length");
offset_distance += last_width / 2 + width/2;
last_width = width;
while (storage.skirt_brim[extruder].polygonLength() < minimal_length)
{
storage.skirt_brim[extruder].add(first_layer_outline.offset(offset_distance, ClipperLib::jtRound));
offset_distance += width;
}
}
}
}
}//namespace cura
+59
Ver Arquivo
@@ -0,0 +1,59 @@
/** Copyright (C) 2013 David Braam - Released under terms of the AGPLv3 License */
#ifndef SKIRT_BRIM_H
#define SKIRT_BRIM_H
#include "sliceDataStorage.h"
namespace cura
{
class SkirtBrim
{
public:
/*!
* Generate skirt or brim (depending on parameters).
*
* When \p distance > 0 and \p count == 1 a skirt is generated, which has
* slightly different configuration. Otherwise, a brim is generated.
*
* \param storage Storage containing the parts at the first layer.
* \param distance The distance of the first outset from the parts at the first
* layer.
* \param primary_line_count Number of outsets / brim lines of the primary extruder.
* \param outside_only Whether to only generate a brim on the outside, rather than also in holes
*/
static void generate(SliceDataStorage& storage, int distance, unsigned int primary_line_count, bool outside_only);
private:
/*!
* Get the reference outline of the first layer around which to generate the first brim/skirt line.
*
* This function may change the support polygons in the first layer
* in order to meet criteria for putting brim around the model as well as around the support.
*
* \param storage Storage containing the parts at the first layer.
* \param primary_line_count Number of outsets / brim lines of the primary extruder.
* \param primary_extruder_skirt_brim_line_width Line widths of the initial skirt/brim lines
* \param is_skirt Whether a skirt is being generated vs a brim
* \param outside_only Whether to only generate a brim on the outside, rather than also in holes
* \param[out] first_layer_outline The resulting reference polygons
*/
static void getFirstLayerOutline(SliceDataStorage& storage, const unsigned int primary_line_count, const int primary_extruder_skirt_brim_line_width, const bool is_skirt, const bool outside_only, Polygons& first_layer_outline);
/*!
* Generate the skirt/brim lines around the model
*
* \param storage Storage containing the parts at the first layer.
* \param start_distance The distance of the first outset from the parts at the first
* \param primary_line_count Number of outsets / brim lines of the primary extruder.
* \param primary_extruder_skirt_brim_line_width Line widths of the initial skirt/brim lines
* \param primary_extruder_minimal_length The minimal total length of the skirt/brim lines of the primary extruder
* \param first_layer_outline The reference polygons from which to offset outward to generate skirt/brim lines
* \param[out] skirt_brim_primary_extruder Where to store the resulting brim/skirt lines in
* \return The offset of the last brim/skirt line from the reference polygon \p first_layer_outline
*/
static int generatePrimarySkirtBrimLines(SliceDataStorage& storage, int start_distance, unsigned int primary_line_count, const int primary_extruder_skirt_brim_line_width, const int64_t primary_extruder_minimal_length, const Polygons& first_layer_outline, Polygons& skirt_brim_primary_extruder);
};
}//namespace cura
#endif //SKIRT_BRIM_H
+25
Ver Arquivo
@@ -0,0 +1,25 @@
#ifndef SPACE_FILL_TYPE
#define SPACE_FILL_TYPE
namespace cura
{
/*!
* Enum class enumerating the strategies with which an area can be occupied with filament
*
* The walls/perimeters are Polygons
* ZigZag infill is PolyLines, and so is following mesh surface mode for non-polygon surfaces
* Grid, Triangles and lines infill is Lines
*/
enum class SpaceFillType
{
None,
Polygons,
PolyLines,
Lines
};
} // namespace cura
#endif // SPACE_FILL_TYPE
+80
Ver Arquivo
@@ -0,0 +1,80 @@
/** Copyright (C) 2013 David Braam - Released under terms of the AGPLv3 License */
#include "WallsComputation.h"
#include "utils/polygonUtils.h"
namespace cura {
WallsComputation::WallsComputation(int wall_0_inset, int line_width_0, int line_width_x, int insetCount, bool recompute_outline_based_on_outer_wall)
: wall_0_inset(wall_0_inset)
, line_width_0(line_width_0)
, line_width_x(line_width_x)
, insetCount(insetCount)
, recompute_outline_based_on_outer_wall(recompute_outline_based_on_outer_wall)
{
}
void WallsComputation::generateInsets(SliceLayerPart* part)
{
if (insetCount == 0)
{
part->insets.push_back(part->outline);
part->print_outline = part->outline;
return;
}
for(int i=0; i<insetCount; i++)
{
part->insets.push_back(Polygons());
if (i == 0)
{
part->insets[0] = part->outline.offset(-line_width_0 / 2 - wall_0_inset);
} else if (i == 1)
{
part->insets[1] = part->insets[0].offset(-line_width_0 / 2 + wall_0_inset - line_width_x / 2);
} else
{
part->insets[i] = part->insets[i-1].offset(-line_width_x);
}
//Finally optimize all the polygons. Every point removed saves time in the long run.
part->insets[i].simplify();
part->insets[i].removeDegenerateVerts();
if (i == 0)
{
if (recompute_outline_based_on_outer_wall)
{
part->print_outline = part->insets[0].offset(line_width_0 / 2);
}
else
{
part->print_outline = part->outline;
}
}
if (part->insets[i].size() < 1)
{
part->insets.pop_back();
break;
}
}
}
void WallsComputation::generateInsets(SliceLayer* layer)
{
for(unsigned int partNr = 0; partNr < layer->parts.size(); partNr++)
{
generateInsets(&layer->parts[partNr]);
}
//Remove the parts which did not generate an inset. As these parts are too small to print,
// and later code can now assume that there is always minimal 1 inset line.
for(unsigned int partNr = 0; partNr < layer->parts.size(); partNr++)
{
if (layer->parts[partNr].insets.size() < 1)
{
layer->parts.erase(layer->parts.begin() + partNr);
partNr -= 1;
}
}
}
}//namespace cura
+69
Ver Arquivo
@@ -0,0 +1,69 @@
/** Copyright (C) 2013 David Braam - Released under terms of the AGPLv3 License */
#ifndef WALLS_COMPUTATION_H
#define WALLS_COMPUTATION_H
#include "sliceDataStorage.h"
namespace cura
{
/*!
* Function container for computing the outer walls / insets / perimeters polygons of a layer
*/
class WallsComputation
{
public:
/*!
* The offset applied to the outer wall
*/
int wall_0_inset;
/*!
* line width of the outer wall
*/
int line_width_0;
/*!
* line width of other walls
*/
int line_width_x;
/*!
* The number of insets to to generate
*/
int insetCount;
/*!
* Whether to compute a more accurate poly representation of the printed outlines, based on the outer wall
*/
bool recompute_outline_based_on_outer_wall;
/*!
* Basic constructor initializing the parameters with which to perform the walls computation
*
* \param wall_0_inset The offset applied to the outer wall
* \param line_width_0 line width of the outer wall
* \param line_width_x line width of other walls
* \param insetCount The number of insets to to generate
* \param recompute_outline_based_on_outer_wall Whether to compute a more accurate poly representation of the printed outlines, based on the outer wall
*/
WallsComputation(int wall_0_inset, int line_width_0, int line_width_x, int insetCount, bool recompute_outline_based_on_outer_wall);
/*!
* Generates the insets / perimeters for all parts in a layer.
*
* Note that the second inset gets offsetted by WallsComputation::line_width_0 instead of the first,
* which leads to better results for a smaller WallsComputation::line_width_0 than WallsComputation::line_width_x and when printing the outer wall last.
*
* \param layer The layer for which to generate the insets.
*/
void generateInsets(SliceLayer* layer);
private:
/*!
* Generates the insets / perimeters for a single layer part.
*
* \param part The part for which to generate the insets.
*/
void generateInsets(SliceLayerPart* part);
};
}//namespace cura
#endif//WALLS_COMPUTATION_H
+476
Ver Arquivo
@@ -0,0 +1,476 @@
#include "Weaver.h"
#include <cmath> // sqrt
#include <fstream> // debug IO
#include <unistd.h>
#include "progress/Progress.h"
#include "weaveDataStorage.h"
#include "PrintFeature.h"
namespace cura
{
void Weaver::weave(MeshGroup* meshgroup)
{
wireFrame.meshgroup = meshgroup;
int maxz = meshgroup->max().z;
int layer_count = (maxz - initial_layer_thickness) / connectionHeight + 1;
std::cerr << "Layer count: " << layer_count << "\n";
std::vector<cura::Slicer*> slicerList;
for(Mesh& mesh : meshgroup->meshes)
{
cura::Slicer* slicer = new cura::Slicer(&mesh, initial_layer_thickness, connectionHeight, layer_count, mesh.getSettingBoolean("meshfix_keep_open_polygons"), mesh.getSettingBoolean("meshfix_extensive_stitching"));
slicerList.push_back(slicer);
}
int starting_layer_idx;
{ // find first non-empty layer
for (starting_layer_idx = 0; starting_layer_idx < layer_count; starting_layer_idx++)
{
Polygons parts;
for (cura::Slicer* slicer : slicerList)
parts.add(slicer->layers[starting_layer_idx].polygons);
if (parts.size() > 0)
break;
}
if (starting_layer_idx > 0)
{
logWarning("First %i layers are empty!\n", starting_layer_idx);
}
}
std::cerr<< "chainifying layers..." << std::endl;
{
int starting_z = -1;
for (cura::Slicer* slicer : slicerList)
wireFrame.bottom_outline.add(slicer->layers[starting_layer_idx].polygons);
CommandSocket::sendPolygons(PrintFeatureType::OuterWall, /*0,*/ wireFrame.bottom_outline, 1);
if (slicerList.empty()) //Wait, there is nothing to slice.
{
wireFrame.z_bottom = 0;
}
else
{
wireFrame.z_bottom = slicerList[0]->layers[starting_layer_idx].z;
}
Point starting_point_in_layer;
if (wireFrame.bottom_outline.size() > 0)
starting_point_in_layer = (wireFrame.bottom_outline.max() + wireFrame.bottom_outline.min()) / 2;
else
starting_point_in_layer = (Point(0,0) + meshgroup->max() + meshgroup->min()) / 2;
Progress::messageProgressStage(Progress::Stage::INSET_SKIN, nullptr);
for (int layer_idx = starting_layer_idx + 1; layer_idx < layer_count; layer_idx++)
{
Progress::messageProgress(Progress::Stage::INSET_SKIN, layer_idx+1, layer_count); // abuse the progress system of the normal mode of CuraEngine
Polygons parts1;
for (cura::Slicer* slicer : slicerList)
parts1.add(slicer->layers[layer_idx].polygons);
Polygons chainified;
chainify_polygons(parts1, starting_point_in_layer, chainified, false);
CommandSocket::sendPolygons(PrintFeatureType::OuterWall, /*layer_idx - starting_layer_idx,*/ chainified, 1);
if (chainified.size() > 0)
{
if (starting_z == -1) starting_z = slicerList[0]->layers[layer_idx-1].z;
wireFrame.layers.emplace_back();
WeaveLayer& layer = wireFrame.layers.back();
layer.z0 = slicerList[0]->layers[layer_idx-1].z - starting_z;
layer.z1 = slicerList[0]->layers[layer_idx].z - starting_z;
layer.supported = chainified;
starting_point_in_layer = layer.supported.back().back();
}
}
}
std::cerr<< "finding horizontal parts..." << std::endl;
{
Polygons* lower_top_parts = &wireFrame.bottom_outline;
Progress::messageProgressStage(Progress::Stage::SUPPORT, nullptr);
for (unsigned int layer_idx = 0; layer_idx < wireFrame.layers.size(); layer_idx++)
{
Progress::messageProgress(Progress::Stage::SUPPORT, layer_idx+1, wireFrame.layers.size()); // abuse the progress system of the normal mode of CuraEngine
WeaveLayer& layer = wireFrame.layers[layer_idx];
Polygons empty;
Polygons& layer_above = (layer_idx+1 < wireFrame.layers.size())? wireFrame.layers[layer_idx+1].supported : empty;
createHorizontalFill(*lower_top_parts, layer, layer_above, layer.z1);
lower_top_parts = &layer.supported;
}
}
// at this point layer.supported still only contains the polygons to be connected
// when connecting layers, we further add the supporting polygons created by the roofs
std::cerr<< "connecting layers..." << std::endl;
{
Polygons* lower_top_parts = &wireFrame.bottom_outline;
int last_z = wireFrame.z_bottom;
for (unsigned int layer_idx = 0; layer_idx < wireFrame.layers.size(); layer_idx++) // use top of every layer but the last
{
WeaveLayer& layer = wireFrame.layers[layer_idx];
connect_polygons(*lower_top_parts, last_z, layer.supported, layer.z1, layer);
layer.supported.add(layer.roofs.roof_outlines);
lower_top_parts = &layer.supported;
last_z = layer.z1;
}
}
{ // roofs:
if (!wireFrame.layers.empty()) //If there are no layers, create no roof.
{
WeaveLayer& top_layer = wireFrame.layers.back();
Polygons to_be_supported; // empty for the top layer
fillRoofs(top_layer.supported, to_be_supported, -1, top_layer.z1, top_layer.roofs);
}
}
{ // bottom:
if (!wireFrame.layers.empty()) //If there are no layers, create no bottom.
{
Polygons to_be_supported; // is empty for the bottom layer, cause the order of insets doesn't really matter (in a sense everything is to be supported)
fillRoofs(wireFrame.bottom_outline, to_be_supported, -1, wireFrame.layers.front().z0, wireFrame.bottom_infill);
}
}
}
void Weaver::createHorizontalFill(Polygons& lower_top_parts, WeaveLayer& layer, Polygons& layer_above, int z1)
{
int64_t bridgable_dist = connectionHeight;
// Polygons& polys_below = lower_top_parts;
Polygons& polys_here = layer.supported;
Polygons& polys_above = layer_above;
{ // roofs
Polygons to_be_supported = polys_above.offset(bridgable_dist);
fillRoofs(polys_here, to_be_supported, -1, layer.z1, layer.roofs);
}
{ // floors
Polygons to_be_supported = polys_above.offset(-bridgable_dist);
fillFloors(polys_here, to_be_supported, 1, layer.z1, layer.roofs);
}
{// optimize away doubly printed regions (boundaries of holes in layer etc.)
for (WeaveRoofPart& inset : layer.roofs.roof_insets)
connections2moves(inset);
}
}
void Weaver::fillRoofs(Polygons& supporting, Polygons& to_be_supported, int direction, int z, WeaveRoof& horizontals)
{
std::vector<WeaveRoofPart>& insets = horizontals.roof_insets;
if (supporting.size() == 0) return; // no parts to start the roof from!
Polygons roofs = supporting.difference(to_be_supported);
roofs = roofs.offset(-roof_inset).offset(roof_inset);
if (roofs.size() == 0) return;
Polygons roof_outlines;
Polygons roof_holes;
{ // split roofs into outlines and holes
std::vector<PolygonsPart> roof_parts = roofs.splitIntoParts();
for (PolygonsPart& roof_part : roof_parts)
{
roof_outlines.add(roof_part[0]);
for (unsigned int hole_idx = 1; hole_idx < roof_part.size(); hole_idx++)
{
roof_holes.add(roof_part[hole_idx]);
roof_holes.back().reverse();
}
}
}
Polygons supporting_outlines;
std::vector<PolygonsPart> supporting_parts = supporting.splitIntoParts();
for (PolygonsPart& supporting_part : supporting_parts)
supporting_outlines.add(supporting_part[0]); // only add outlines, not the holes
Polygons inset1;
Polygons last_inset;
Polygons last_supported = supporting;
for (Polygons inset0 = supporting_outlines; inset0.size() > 0; inset0 = last_inset)
{
last_inset = inset0.offset(direction * roof_inset, ClipperLib::jtRound);
inset1 = last_inset.intersection(roof_outlines); // stay within roof area
inset1 = inset1.unionPolygons(roof_holes);// make insets go around holes
if (inset1.size() == 0) break;
insets.emplace_back();
connect(last_supported, z, inset1, z, insets.back(), true);
inset1 = inset1.remove(roof_holes); // throw away holes which appear in every intersection
inset1 = inset1.remove(roof_outlines);// throw away fully filled regions
last_supported = insets.back().supported; // chainified
}
horizontals.roof_outlines.add(roofs); // TODO just add the new lines, not the lines of the roofs which are already supported ==> make outlines into a connection from which we only print the top, not the connection
}
void Weaver::fillFloors(Polygons& supporting, Polygons& to_be_supported, int direction, int z, WeaveRoof& horizontals)
{
std::vector<WeaveRoofPart>& outsets = horizontals.roof_insets;
if (to_be_supported.size() == 0) return; // no parts to start the floor from!
if (supporting.size() == 0) return; // no parts to start the floor from!
Polygons floors = to_be_supported.difference(supporting);
floors = floors.offset(-roof_inset).offset(roof_inset);
if (floors.size() == 0) return;
std::vector<PolygonsPart> floor_parts = floors.splitIntoParts();
Polygons floor_outlines;
Polygons floor_holes;
for (PolygonsPart& floor_part : floor_parts)
{
floor_outlines.add(floor_part[0]);
for (unsigned int hole_idx = 1; hole_idx < floor_part.size(); hole_idx++)
{
floor_holes.add(floor_part[hole_idx]);
//floor_holes.back().reverse();
}
}
Polygons outset1;
Polygons last_supported = supporting;
for (Polygons outset0 = supporting; outset0.size() > 0; outset0 = outset1)
{
outset1 = outset0.offset(roof_inset * direction, ClipperLib::jtRound).intersection(floors);
outset1 = outset1.remove(floor_holes); // throw away holes which appear in every intersection
outset1 = outset1.remove(floor_outlines); // throw away holes which appear in every intersection
outsets.emplace_back();
connect(last_supported, z, outset1, z, outsets.back(), true);
outset1 = outset1.remove(floor_outlines);// throw away fully filled regions
last_supported = outsets.back().supported; // chainified
}
horizontals.roof_outlines.add(floors);
}
void Weaver::connections2moves(WeaveRoofPart& inset)
{
bool include_half_of_last_down = true;
for (WeaveConnectionPart& part : inset.connections)
{
std::vector<WeaveConnectionSegment>& segments = part.connection.segments;
for (unsigned int idx = 0; idx < part.connection.segments.size(); idx += 2)
{
WeaveConnectionSegment& segment = segments[idx];
assert(segment.segmentType == WeaveSegmentType::UP);
Point3 from = (idx == 0)? part.connection.from : segments[idx-1].to;
bool skipped = (segment.to - from).vSize2() < line_width * line_width;
if (skipped)
{
unsigned int begin = idx;
for (; idx < segments.size(); idx += 2)
{
WeaveConnectionSegment& segment = segments[idx];
assert(segments[idx].segmentType == WeaveSegmentType::UP);
Point3 from = (idx == 0)? part.connection.from : segments[idx-1].to;
bool skipped = (segment.to - from).vSize2() < line_width * line_width;
if (!skipped)
{
break;
}
}
int end = idx - ((include_half_of_last_down)? 2 : 1);
if (idx >= segments.size())
segments.erase(segments.begin() + begin, segments.end());
else
{
segments.erase(segments.begin() + begin, segments.begin() + end);
if (begin < segments.size())
{
segments[begin].segmentType = WeaveSegmentType::MOVE;
if (include_half_of_last_down)
segments[begin+1].segmentType = WeaveSegmentType::DOWN_AND_FLAT;
}
idx = begin + ((include_half_of_last_down)? 2 : 1);
}
}
}
}
}
void Weaver::connect(Polygons& parts0, int z0, Polygons& parts1, int z1, WeaveConnection& result, bool include_last)
{
// TODO: convert polygons (with outset + difference) such that after printing the first polygon, we can't be in the way of the printed stuff
// something like:
// for (m > n)
// parts[m] = parts[m].difference(parts[n].offset(nozzle_top_diameter))
// according to the printing order!
//
// OR! :
//
// unify different parts if gap is too small
Polygons& supported = result.supported;
if (parts1.size() == 0) return;
Point& start_close_to = (parts0.size() > 0)? parts0.back().back() : parts1.back().back();
chainify_polygons(parts1, start_close_to, supported, include_last);
if (parts0.size() == 0) return;
connect_polygons(parts0, z0, supported, z1, result);
}
void Weaver::chainify_polygons(Polygons& parts1, Point start_close_to, Polygons& result, bool include_last)
{
for (unsigned int prt = 0 ; prt < parts1.size(); prt++)
{
const PolygonRef upperPart = parts1[prt];
ClosestPolygonPoint closestInPoly = PolygonUtils::findClosest(start_close_to, upperPart);
PolygonRef part_top = result.newPoly();
GivenDistPoint next_upper;
bool found = true;
int idx = 0;
for (Point upper_point = upperPart[closestInPoly.point_idx]; found; upper_point = next_upper.location)
{
found = PolygonUtils::getNextPointWithDistance(upper_point, nozzle_top_diameter, upperPart, idx, closestInPoly.point_idx, next_upper);
if (!found)
{
break;
}
part_top.add(upper_point);
idx = next_upper.pos;
}
if (part_top.size() > 0)
start_close_to = part_top.back();
else
result.remove(result.size()-1);
}
}
void Weaver::connect_polygons(Polygons& supporting, int z0, Polygons& supported, int z1, WeaveConnection& result)
{
if (supporting.size() < 1)
{
std::cerr << "lower layer has zero parts!\n";
return;
}
result.z0 = z0;
result.z1 = z1;
std::vector<WeaveConnectionPart>& parts = result.connections;
for (unsigned int prt = 0 ; prt < supported.size(); prt++)
{
const PolygonRef upperPart = supported[prt];
parts.emplace_back(prt);
WeaveConnectionPart& part = parts.back();
PolyLine3& connection = part.connection;
Point3 last_upper;
bool firstIter = true;
for (const Point& upper_point : upperPart)
{
ClosestPolygonPoint lowerPolyPoint = PolygonUtils::findClosest(upper_point, supporting);
Point& lower = lowerPolyPoint.location;
Point3 lower3 = Point3(lower.X, lower.Y, z0);
Point3 upper3 = Point3(upper_point.X, upper_point.Y, z1);
if (firstIter)
connection.from = lower3;
else
connection.segments.emplace_back<>(lower3, WeaveSegmentType::DOWN);
connection.segments.emplace_back<>(upper3, WeaveSegmentType::UP);
last_upper = upper3;
firstIter = false;
}
}
}
}//namespace cura
+150
Ver Arquivo
@@ -0,0 +1,150 @@
#ifndef WEAVER_H
#define WEAVER_H
#include "weaveDataStorage.h"
#include "commandSocket.h"
#include "settings/settings.h"
#include "MeshGroup.h"
#include "slicer.h"
#include "utils/NoCopy.h"
#include "utils/polygon.h"
#include "utils/polygonUtils.h"
namespace cura
{
/*!
* The main weaver / WirePrint / wireframe printing class, which computes the basic paths to be followed.
*/
class Weaver : public SettingsMessenger, NoCopy
{
friend class Wireframe2gcode;
private:
static const int HIGHER_BEND_NO_STRAIGHTEN = 0;
static const int MOVE_TO_STRAIGHTEN = 1;
static const int RETRACT_TO_STRAIGHTEN = 2;
int initial_layer_thickness;
int connectionHeight;
int line_width;
int roof_inset;
int nozzle_outer_diameter;
double nozzle_expansion_angle;
int nozzle_clearance;
int nozzle_top_diameter;
public:
Weaver(SettingsBase* settings_base) : SettingsMessenger(settings_base)
{
initial_layer_thickness = getSettingInMicrons("layer_height_0");
connectionHeight = getSettingInMicrons("wireframe_height");
line_width = getSettingInMicrons("wall_line_width_x");
roof_inset = getSettingInMicrons("wireframe_roof_inset");
nozzle_outer_diameter = getSettingInMicrons("machine_nozzle_tip_outer_diameter"); // ___ ___ .
nozzle_expansion_angle = getSettingInAngleRadians("machine_nozzle_expansion_angle"); // \_U_/ .
nozzle_clearance = getSettingInMicrons("wireframe_nozzle_clearance"); // at least line width
nozzle_top_diameter = tan(nozzle_expansion_angle) * connectionHeight + nozzle_outer_diameter + nozzle_clearance;
}
/*!
* This is the main function for Neith / Weaving / WirePrinting / Webbed printing.
* Creates a wireframe for the model consisting of horizontal 'flat' parts and connections between consecutive flat parts consisting of UP moves and diagonally DOWN moves.
*
* \param objects The objects for which to create a wireframe print
*/
void weave(MeshGroup* objects);
private:
WireFrame wireFrame;
/*!
* Connect two polygons, chainify the second and generate connections from it, supporting on the first polygon.
*
* \param supporting The polygons from which to start the connection
* \param z0 The height of the \p supporting
* \param supported The polygons to be supported by the connection from \p supporting to \p supported
* \param z1 the height of \p supported
* \param include_last Whether the last full link should be included in the chainified \p parts1 if the last link would be shorter than the normal link size.
*/
void connect(Polygons& parts0, int z0, Polygons& parts1, int z1, WeaveConnection& result, bool include_last);
/*!
* Convert polygons, such that they consist of segments/links of uniform size, namely \p nozzle_top_diameter.
*
* \param parts1 The polygons to be chainified
* \param start_close_to The point from which to start the first link
* \param include_last governs whether the last segment is smaller or grater than the \p nozzle_top_diameter.
* If true, the last segment may be smaller.
*/
void chainify_polygons(Polygons& parts1, Point start_close_to, Polygons& result, bool include_last);
/*!
* The main weaving function.
* Generate connections between two polygons.
* The connections consist of zig zags of which the zig is a line from a point in \p supported to the closest point in \p supporting
* and the zag is a diagonal line from the same point in \p supported to a point in \p supporting
* with a distance equal to Weaver::nozzle_top_diameter from the other point in \p supporting of the zig.
*
* \param supporting The polygons from which to start the connection
* \param z0 The height of the \p supporting
* \param supported The polygons to be supported by the connection from \p supporting to \p supported
* \param z1 the height of \p supported
* \param result The resulting connection
*/
void connect_polygons(Polygons& supporting, int z0, Polygons& supported, int z1, WeaveConnection& result);
/*!
* Creates the roofs and floors which are laid down horizontally.
*/
void createHorizontalFill(Polygons& lower_top_parts, WeaveLayer& layer, Polygons& layer_above, int z1);
/*!
* Fill roofs starting from the outlines of \p supporting.
* The area to be filled in is difference( \p to_be_supported , \p supporting ).
*
* The basic algorithm performs insets on \p supported until the whole area of \p to_be_supported is filled.
* In order to not fill holes in the roof, the hole-areas are unioned with the insets, which results in connections where the UP move has close to zero length;
* pieces of the area between two consecutive insets have close to zero distance at these points.
* These parts of the horizontal infills are converted into moves by the function \p connections2moves.
*
* Note that the new inset is computed from the last inset, while the connections are between the last chainified inset and the new chainified inset.
*
*/
void fillRoofs(Polygons& supporting, Polygons& to_be_supported, int direction, int z, WeaveRoof& roofs);
/*!
* Fill floors starting from the outlines of \p supporting.
* The area to be filled in is \p floors = difference( \p to_be_supported , \p supporting ).
*
* The basic algorithm performs outsets until the whole area of [to_be_supported] is filled.
* In order to not fill too much, the outsets are intersected with the [floors] area, which results in connections where the UP move has close to zero length.
* These parts of the horizontal infills are converted into moves by the function [connections2moves].
*
* The first supporting polygons are \p supporting while the supporting polygons in consecutive iterations are sub-areas of \p floors.
*
* Note that the new outset is computed from the last outset, while the connections are between the last chainified outset and the new (chainified) outset.
*
*/
void fillFloors(Polygons& supporting, Polygons& to_be_supported, int direction, int z, WeaveRoof& roofs);
/*!
* Filter out parts of connections with small distances; replace by moves.
*
*/
void connections2moves(WeaveRoofPart& inset);
};
}//namespace cura
#endif//WEAVER_H
+642
Ver Arquivo
@@ -0,0 +1,642 @@
#include "Wireframe2gcode.h"
#include <cmath> // sqrt
#include <fstream> // debug IO
#include "utils/math.h"
#include "utils/logoutput.h"
#include "weaveDataStorage.h"
#include "progress/Progress.h"
#include "pathOrderOptimizer.h" //For skirt/brim.
namespace cura
{
void Wireframe2gcode::writeGCode()
{
gcode.preSetup(wireFrame.meshgroup);
gcode.setInitialTemps(*wireFrame.meshgroup);
if (CommandSocket::getInstance())
CommandSocket::getInstance()->beginGCode();
processStartingCode();
int maxObjectHeight;
if (wireFrame.layers.empty())
{
maxObjectHeight = 0;
}
else
{
maxObjectHeight = wireFrame.layers.back().z1;
}
gcode.setZ(initial_layer_thickness);
processSkirt();
unsigned int total_layers = wireFrame.layers.size();
gcode.writeLayerComment(0);
gcode.writeTypeComment(PrintFeatureType::SkirtBrim);
for (PolygonRef bottom_part : wireFrame.bottom_infill.roof_outlines)
{
if (bottom_part.size() == 0) continue;
writeMoveWithRetract(bottom_part[bottom_part.size()-1]);
for (Point& segment_to : bottom_part)
{
gcode.writeMove(segment_to, speedBottom, extrusion_mm3_per_mm_flat);
}
}
// bottom:
Polygons empty_outlines;
writeFill(wireFrame.bottom_infill.roof_insets, empty_outlines,
[this](Wireframe2gcode& thiss, WeaveRoofPart& inset, WeaveConnectionPart& part, unsigned int segment_idx) {
WeaveConnectionSegment& segment = part.connection.segments[segment_idx];
if (segment.segmentType == WeaveSegmentType::MOVE || segment.segmentType == WeaveSegmentType::DOWN_AND_FLAT) // this is the case when an inset overlaps with a hole
{
writeMoveWithRetract(segment.to);
} else
{
gcode.writeMove(segment.to, speedBottom, extrusion_mm3_per_mm_connection);
}
}
,
[this](Wireframe2gcode& thiss, WeaveConnectionSegment& segment) {
if (segment.segmentType == WeaveSegmentType::MOVE)
writeMoveWithRetract(segment.to);
else if (segment.segmentType == WeaveSegmentType::DOWN_AND_FLAT)
return; // do nothing
else
gcode.writeMove(segment.to, speedBottom, extrusion_mm3_per_mm_flat);
}
);
Progress::messageProgressStage(Progress::Stage::EXPORT, nullptr);
for (unsigned int layer_nr = 0; layer_nr < wireFrame.layers.size(); layer_nr++)
{
Progress::messageProgress(Progress::Stage::EXPORT, layer_nr+1, total_layers); // abuse the progress system of the normal mode of CuraEngine
WeaveLayer& layer = wireFrame.layers[layer_nr];
gcode.writeLayerComment(layer_nr+1);
double fanSpeed = getSettingInPercentage("cool_fan_speed_max");
if (layer_nr == 0)
fanSpeed = getSettingInPercentage("cool_fan_speed_min");
gcode.writeFanCommand(fanSpeed);
for (unsigned int part_nr = 0; part_nr < layer.connections.size(); part_nr++)
{
WeaveConnectionPart& part = layer.connections[part_nr];
if (part.connection.segments.size() == 0) continue;
gcode.writeTypeComment(PrintFeatureType::Support); // connection
{
if (vSize2(gcode.getPositionXY() - part.connection.from) > connectionHeight)
{
Point3 point_same_height(part.connection.from.x, part.connection.from.y, layer.z1+100);
writeMoveWithRetract(point_same_height);
}
writeMoveWithRetract(part.connection.from);
for (unsigned int segment_idx = 0; segment_idx < part.connection.segments.size(); segment_idx++)
{
handle_segment(layer, part, segment_idx);
}
}
gcode.writeTypeComment(PrintFeatureType::OuterWall); // top
{
for (unsigned int segment_idx = 0; segment_idx < part.connection.segments.size(); segment_idx++)
{
WeaveConnectionSegment& segment = part.connection.segments[segment_idx];
if (segment.segmentType == WeaveSegmentType::DOWN) continue;
if (segment.segmentType == WeaveSegmentType::MOVE)
{
writeMoveWithRetract(segment.to);
} else
{
gcode.writeMove(segment.to, speedFlat, extrusion_mm3_per_mm_flat);
gcode.writeDelay(flat_delay);
}
}
}
}
// roofs:
gcode.setZ(layer.z1);
std::function<void (Wireframe2gcode& thiss, WeaveRoofPart& inset, WeaveConnectionPart& part, unsigned int segment_idx)>
handle_roof = &Wireframe2gcode::handle_roof_segment;
writeFill(layer.roofs.roof_insets, layer.roofs.roof_outlines,
handle_roof,
[this](Wireframe2gcode& thiss, WeaveConnectionSegment& segment) { // handle flat segments
if (segment.segmentType == WeaveSegmentType::MOVE)
{
writeMoveWithRetract(segment.to);
} else if (segment.segmentType == WeaveSegmentType::DOWN_AND_FLAT)
{
// do nothing
} else
{
gcode.writeMove(segment.to, speedFlat, extrusion_mm3_per_mm_flat);
gcode.writeDelay(flat_delay);
}
});
}
gcode.setZ(maxObjectHeight);
gcode.writeRetraction(&standard_retraction_config);
gcode.updateTotalPrintTime();
gcode.writeDelay(0.3);
gcode.writeFanCommand(0);
finalize();
}
void Wireframe2gcode::go_down(WeaveLayer& layer, WeaveConnectionPart& part, unsigned int segment_idx)
{
WeaveConnectionSegment& segment = part.connection.segments[segment_idx];
Point3 from = (segment_idx == 0)? part.connection.from : part.connection.segments[segment_idx - 1].to;
if (go_back_to_last_top)
gcode.writeMove(from, speedDown, 0);
if (straight_first_when_going_down <= 0)
{
gcode.writeMove(segment.to, speedDown, extrusion_mm3_per_mm_connection);
} else
{
Point3& to = segment.to;
Point3 from = gcode.getPosition();// segment.from;
Point3 vec = to - from;
Point3 in_between = from + vec * straight_first_when_going_down / 100;
Point3 up(in_between.x, in_between.y, from.z);
int64_t new_length = (up - from).vSize() + (to - up).vSize() + 5;
int64_t orr_length = vec.vSize();
double enlargement = new_length / orr_length;
gcode.writeMove(up, speedDown*enlargement, extrusion_mm3_per_mm_connection / enlargement);
gcode.writeMove(to, speedDown*enlargement, extrusion_mm3_per_mm_connection / enlargement);
}
gcode.writeDelay(bottom_delay);
if (up_dist_half_speed > 0)
{
gcode.writeMove(Point3(0,0,up_dist_half_speed) + gcode.getPosition(), speedUp / 2, extrusion_mm3_per_mm_connection * 2);
}
}
void Wireframe2gcode::strategy_knot(WeaveLayer& layer, WeaveConnectionPart& part, unsigned int segment_idx)
{
WeaveConnectionSegment& segment = part.connection.segments[segment_idx];
gcode.writeMove(segment.to, speedUp, extrusion_mm3_per_mm_connection);
Point3 next_vector;
if (segment_idx + 1 < part.connection.segments.size())
{
WeaveConnectionSegment& next_segment = part.connection.segments[segment_idx+1];
next_vector = next_segment.to - segment.to;
} else
{
next_vector = part.connection.segments[0].to - segment.to;
}
Point next_dir_2D(next_vector.x, next_vector.y);
next_dir_2D = next_dir_2D * top_jump_dist / vSize(next_dir_2D);
Point3 next_dir (next_dir_2D.X / 2, next_dir_2D.Y / 2, -top_jump_dist);
Point3 current_pos = gcode.getPosition();
gcode.writeMove(current_pos - next_dir, speedUp, 0);
gcode.writeDelay(top_delay);
gcode.writeMove(current_pos + next_dir_2D, speedUp, 0);
}
void Wireframe2gcode::strategy_retract(WeaveLayer& layer, WeaveConnectionPart& part, unsigned int segment_idx)
{
WeaveConnectionSegment& segment = part.connection.segments[segment_idx];
Point3 from = (segment_idx == 0)? part.connection.from : part.connection.segments[segment_idx - 1].to;
RetractionConfig retraction_config;
// TODO: get these from the settings!
retraction_config.distance = 500; //INT2MM(getSettingInt("retraction_amount"))
retraction_config.prime_volume = 0;//INT2MM(getSettingInt("retractionPrime
retraction_config.speed = 20; // 40;
retraction_config.primeSpeed = 15; // 30;
retraction_config.zHop = 0; //getSettingInt("retraction_hop");
retraction_config.retraction_count_max = getSettingAsCount("retraction_count_max");
retraction_config.retraction_extrusion_window = getSettingInMillimeters("retraction_extrusion_window");
retraction_config.retraction_min_travel_distance = getSettingInMicrons("retraction_min_travel");
double top_retract_pause = 2.0;
int retract_hop_dist = 1000;
bool after_retract_hop = false;
//bool go_horizontal_first = true;
bool lower_retract_start = true;
Point3& to = segment.to;
if (lower_retract_start)
{
Point3 vec = to - from;
Point3 lowering = vec * retract_hop_dist / 2 / vec.vSize();
Point3 lower = to - lowering;
gcode.writeMove(lower, speedUp, extrusion_mm3_per_mm_connection);
gcode.writeRetraction(&retraction_config);
gcode.writeMove(to + lowering, speedUp, 0);
gcode.writeDelay(top_retract_pause);
if (after_retract_hop)
gcode.writeMove(to + Point3(0, 0, retract_hop_dist), speedFlat, 0);
} else
{
gcode.writeMove(to, speedUp, extrusion_mm3_per_mm_connection);
gcode.writeRetraction(&retraction_config);
gcode.writeMove(to + Point3(0, 0, retract_hop_dist), speedFlat, 0);
gcode.writeDelay(top_retract_pause);
if (after_retract_hop)
gcode.writeMove(to + Point3(0, 0, retract_hop_dist*3), speedFlat, 0);
}
}
void Wireframe2gcode::strategy_compensate(WeaveLayer& layer, WeaveConnectionPart& part, unsigned int segment_idx)
{
WeaveConnectionSegment& segment = part.connection.segments[segment_idx];
Point3 from = (segment_idx == 0)? part.connection.from : part.connection.segments[segment_idx - 1].to;
Point3 to = segment.to + Point3(0, 0, fall_down*(segment.to - from).vSize() / connectionHeight);
Point3 vector = segment.to - from;
Point3 dir = vector * drag_along / vector.vSize();
Point3 next_point;
if (segment_idx + 1 < part.connection.segments.size())
{
WeaveConnectionSegment& next_segment = part.connection.segments[segment_idx+1];
next_point = next_segment.to;
} else
{
next_point = part.connection.segments[0].to;
}
Point3 next_vector = next_point - segment.to;
Point next_dir_2D(next_vector.x, next_vector.y);
int64_t next_dir_2D_size = vSize(next_dir_2D);
if (next_dir_2D_size > 0)
next_dir_2D = next_dir_2D * drag_along / next_dir_2D_size;
Point3 next_dir (next_dir_2D.X, next_dir_2D.Y, 0);
Point3 newTop = to - next_dir + dir;
int64_t orrLength = (segment.to - from).vSize() + next_vector.vSize() + 1; // + 1 in order to avoid division by zero
int64_t newLength = (newTop - from).vSize() + (next_point - newTop).vSize() + 1; // + 1 in order to avoid division by zero
gcode.writeMove(newTop, speedUp * newLength / orrLength, extrusion_mm3_per_mm_connection * orrLength / newLength);
}
void Wireframe2gcode::handle_segment(WeaveLayer& layer, WeaveConnectionPart& part, unsigned int segment_idx)
{
WeaveConnectionSegment& segment = part.connection.segments[segment_idx];
switch(segment.segmentType)
{
case WeaveSegmentType::MOVE:
writeMoveWithRetract(segment.to);
break;
case WeaveSegmentType::DOWN:
go_down(layer, part, segment_idx);
break;
case WeaveSegmentType::FLAT:
logWarning("Warning: flat piece in wire print connection.\n");
break;
case WeaveSegmentType::UP:
if (strategy == STRATEGY_KNOT)
{
strategy_knot(layer, part, segment_idx);
} else if (strategy == STRATEGY_RETRACT)
{
strategy_retract(layer, part, segment_idx);
} else if (strategy == STRATEGY_COMPENSATE)
{
strategy_compensate(layer, part, segment_idx);
}
break;
case WeaveSegmentType::DOWN_AND_FLAT:
logError("Down and flat move in non-horizontal connection!");
break;
}
}
void Wireframe2gcode::handle_roof_segment(WeaveRoofPart& inset, WeaveConnectionPart& part, unsigned int segment_idx)
{
WeaveConnectionSegment& segment = part.connection.segments[segment_idx];
Point3 from = (segment_idx == 0)? part.connection.from : part.connection.segments[segment_idx - 1].to;
WeaveConnectionSegment* next_segment = nullptr;
if (segment_idx + 1 < part.connection.segments.size())
next_segment = &part.connection.segments[segment_idx+1];
switch(segment.segmentType)
{
case WeaveSegmentType::MOVE:
case WeaveSegmentType::DOWN_AND_FLAT:
if (next_segment && next_segment->segmentType != WeaveSegmentType::DOWN_AND_FLAT)
{
writeMoveWithRetract(segment.to);
}
break;
case WeaveSegmentType::UP:
{
Point3 to = segment.to + Point3(0, 0, roof_fall_down);
Point3 vector = segment.to - from;
if (vector.vSize2() == 0) return;
Point3 dir = vector * roof_drag_along / vector.vSize();
Point3 next_vector;
if (next_segment)
{
next_vector = next_segment->to - segment.to;
} else
{
next_vector = part.connection.segments[0].to - segment.to;
}
Point next_dir_2D(next_vector.x, next_vector.y);
Point3 detoured = to + dir;
if (vSize2(next_dir_2D) > 0)
{
next_dir_2D = next_dir_2D * roof_drag_along / vSize(next_dir_2D);
Point3 next_dir (next_dir_2D.X, next_dir_2D.Y, 0);
detoured -= next_dir;
}
gcode.writeMove(detoured, speedUp, extrusion_mm3_per_mm_connection);
}
break;
case WeaveSegmentType::DOWN:
gcode.writeMove(segment.to, speedDown, extrusion_mm3_per_mm_connection);
gcode.writeDelay(roof_outer_delay);
break;
case WeaveSegmentType::FLAT:
logError("Flat move in connection!");
break;
}
}
void Wireframe2gcode::writeFill(std::vector<WeaveRoofPart>& infill_insets, Polygons& roof_outlines
, std::function<void (Wireframe2gcode& thiss, WeaveRoofPart& inset, WeaveConnectionPart& part, unsigned int segment_idx)> connectionHandler
, std::function<void (Wireframe2gcode& thiss, WeaveConnectionSegment& p)> flatHandler)
{
// bottom:
gcode.writeTypeComment(PrintFeatureType::Infill);
for (unsigned int inset_idx = 0; inset_idx < infill_insets.size(); inset_idx++)
{
WeaveRoofPart& inset = infill_insets[inset_idx];
for (unsigned int inset_part_nr = 0; inset_part_nr < inset.connections.size(); inset_part_nr++)
{
WeaveConnectionPart& inset_part = inset.connections[inset_part_nr];
std::vector<WeaveConnectionSegment>& segments = inset_part.connection.segments;
gcode.writeTypeComment(PrintFeatureType::Support); // connection
if (segments.size() == 0) continue;
Point3 first_extrusion_from = inset_part.connection.from;
unsigned int first_segment_idx;
for (first_segment_idx = 0; first_segment_idx < segments.size() && segments[first_segment_idx].segmentType == WeaveSegmentType::MOVE; first_segment_idx++)
{ // finds the first segment which is not a move
first_extrusion_from = segments[first_segment_idx].to;
}
if (first_segment_idx == segments.size())
continue;
writeMoveWithRetract(first_extrusion_from);
for (unsigned int segment_idx = first_segment_idx; segment_idx < segments.size(); segment_idx++)
{
connectionHandler(*this, inset, inset_part, segment_idx);
}
gcode.writeTypeComment(PrintFeatureType::InnerWall); // top
for (unsigned int segment_idx = 0; segment_idx < segments.size(); segment_idx++)
{
WeaveConnectionSegment& segment = segments[segment_idx];
if (segment.segmentType == WeaveSegmentType::DOWN) continue;
flatHandler(*this, segment);
}
}
}
gcode.writeTypeComment(PrintFeatureType::OuterWall); // outer perimeter of the flat parts
for (PolygonRef poly : roof_outlines)
{
writeMoveWithRetract(poly[poly.size() - 1]);
for (Point& p : poly)
{
Point3 to(p.X, p.Y, gcode.getPositionZ());
WeaveConnectionSegment segment(to, WeaveSegmentType::FLAT);
flatHandler(*this, segment);
}
}
}
void Wireframe2gcode::writeMoveWithRetract(Point3 to)
{
if ((gcode.getPosition() - to).vSize2() >= nozzle_top_diameter * nozzle_top_diameter * 2 * 2)
gcode.writeRetraction(&standard_retraction_config);
gcode.writeMove(to, moveSpeed, 0);
}
void Wireframe2gcode::writeMoveWithRetract(Point to)
{
if (vSize2(gcode.getPositionXY() - to) >= nozzle_top_diameter * nozzle_top_diameter * 2 * 2)
gcode.writeRetraction(&standard_retraction_config);
gcode.writeMove(to, moveSpeed, 0);
}
Wireframe2gcode::Wireframe2gcode(Weaver& weaver, GCodeExport& gcode, SettingsBase* settings_base)
: SettingsMessenger(settings_base)
, gcode(gcode)
, wireFrame(weaver.wireFrame)
{
initial_layer_thickness = getSettingInMicrons("layer_height_0");
connectionHeight = getSettingInMicrons("wireframe_height");
roof_inset = getSettingInMicrons("wireframe_roof_inset");
filament_diameter = getSettingInMicrons("material_diameter");
line_width = getSettingInMicrons("wall_line_width_x");
flowConnection = getSettingInPercentage("wireframe_flow_connection");
flowFlat = getSettingInPercentage("wireframe_flow_flat");
const double line_area = M_PI * square(INT2MM(line_width) / 2.0);
extrusion_mm3_per_mm_connection = line_area * flowConnection / 100.0;
extrusion_mm3_per_mm_flat = line_area * flowFlat / 100.0;
nozzle_outer_diameter = getSettingInMicrons("machine_nozzle_tip_outer_diameter"); // ___ ___ .
nozzle_head_distance = getSettingInMicrons("machine_nozzle_head_distance"); // | | .
nozzle_expansion_angle = getSettingInAngleRadians("machine_nozzle_expansion_angle"); // \_U_/ .
nozzle_clearance = getSettingInMicrons("wireframe_nozzle_clearance"); // at least line width
nozzle_top_diameter = tan(nozzle_expansion_angle) * connectionHeight + nozzle_outer_diameter + nozzle_clearance;
moveSpeed = 40;
speedBottom = getSettingInMillimetersPerSecond("wireframe_printspeed_bottom");
speedUp = getSettingInMillimetersPerSecond("wireframe_printspeed_up");
speedDown = getSettingInMillimetersPerSecond("wireframe_printspeed_down");
speedFlat = getSettingInMillimetersPerSecond("wireframe_printspeed_flat");
flat_delay = getSettingInSeconds("wireframe_flat_delay");
bottom_delay = getSettingInSeconds("wireframe_bottom_delay");
top_delay = getSettingInSeconds("wireframe_top_delay");
up_dist_half_speed = getSettingInMicrons("wireframe_up_half_speed");
top_jump_dist = getSettingInMicrons("wireframe_top_jump");
fall_down = getSettingInMicrons("wireframe_fall_down");
drag_along = getSettingInMicrons("wireframe_drag_along");
strategy = STRATEGY_COMPENSATE;
if (getSettingString("wireframe_strategy") == "Compensate")
strategy = STRATEGY_COMPENSATE;
if (getSettingString("wireframe_strategy") == "Knot")
strategy = STRATEGY_KNOT;
if (getSettingString("wireframe_strategy") == "Retract")
strategy = STRATEGY_RETRACT;
go_back_to_last_top = false;
straight_first_when_going_down = getSettingInPercentage("wireframe_straight_before_down");
roof_fall_down = getSettingInMicrons("wireframe_roof_fall_down");
roof_drag_along = getSettingInMicrons("wireframe_roof_drag_along");
roof_outer_delay = getSettingInSeconds("wireframe_roof_outer_delay");
standard_retraction_config.distance = getSettingInMillimeters("retraction_amount");
standard_retraction_config.prime_volume = getSettingInCubicMillimeters("retraction_extra_prime_amount");
standard_retraction_config.speed = getSettingInMillimetersPerSecond("retraction_retract_speed");
standard_retraction_config.primeSpeed = getSettingInMillimetersPerSecond("retraction_prime_speed");
standard_retraction_config.zHop = getSettingInMicrons("retraction_hop");
standard_retraction_config.retraction_count_max = getSettingAsCount("retraction_count_max");
standard_retraction_config.retraction_extrusion_window = getSettingInMillimeters("retraction_extrusion_window");
standard_retraction_config.retraction_min_travel_distance = getSettingInMicrons("retraction_min_travel");
}
void Wireframe2gcode::processStartingCode()
{
if (!CommandSocket::isInstantiated())
{
std::string prefix = gcode.getFileHeader();
gcode.writeCode(prefix.c_str());
}
int start_extruder_nr = getSettingAsIndex("adhesion_extruder_nr");
gcode.writeComment("Generated with Cura_SteamEngine " VERSION);
if (gcode.getFlavor() != EGCodeFlavor::ULTIGCODE && gcode.getFlavor() != EGCodeFlavor::GRIFFIN)
{
if (getSettingBoolean("material_bed_temp_prepend"))
{
if (getSettingBoolean("machine_heated_bed") && getSettingInDegreeCelsius("material_bed_temperature") > 0)
{
gcode.writeBedTemperatureCommand(getSettingInDegreeCelsius("material_bed_temperature"), getSettingBoolean("material_bed_temp_wait"));
}
}
if (getSettingBoolean("material_print_temp_prepend"))
{
for (int extruder_nr = 0; extruder_nr < getSettingAsCount("machine_extruder_count"); extruder_nr++)
{
double print_temp = getSettingInDegreeCelsius("material_print_temperature");
gcode.writeTemperatureCommand(extruder_nr, print_temp);
}
if (getSettingBoolean("material_print_temp_wait"))
{
for (int extruder_nr = 0; extruder_nr < getSettingAsCount("machine_extruder_count"); extruder_nr++)
{
double print_temp = getSettingInDegreeCelsius("material_print_temperature");
gcode.writeTemperatureCommand(extruder_nr, print_temp, true);
}
}
}
}
gcode.writeCode(getSettingString("machine_start_gcode").c_str());
if (gcode.getFlavor() == EGCodeFlavor::BFB)
{
gcode.writeComment("enable auto-retraction");
std::ostringstream tmp;
tmp << "M227 S" << (getSettingInMicrons("retraction_amount") * 2560 / 1000) << " P" << (getSettingInMicrons("retraction_amount") * 2560 / 1000);
gcode.writeLine(tmp.str().c_str());
}
else if (gcode.getFlavor() == EGCodeFlavor::GRIFFIN)
{ // initialize extruder trains
gcode.writeCode("T0"); // Toolhead already assumed to be at T0, but writing it just to be safe...
CommandSocket::setSendCurrentPosition(gcode.getPositionXY());
gcode.startExtruder(start_extruder_nr);
constexpr bool wait = true;
gcode.writeTemperatureCommand(start_extruder_nr, getSettingInDegreeCelsius("material_print_temperature"), wait);
gcode.writePrimeTrain(getSettingInMillimetersPerSecond("speed_travel"));
gcode.writeRetraction(&standard_retraction_config);
}
}
void Wireframe2gcode::processSkirt()
{
if (wireFrame.bottom_outline.size() == 0) //If we have no layers, don't create a skirt either.
{
return;
}
Polygons skirt = wireFrame.bottom_outline.offset(100000+5000).offset(-100000);
PathOrderOptimizer order(Point(INT32_MIN, INT32_MIN));
order.addPolygons(skirt);
order.optimize();
for (unsigned int poly_order_idx = 0; poly_order_idx < skirt.size(); poly_order_idx++)
{
unsigned int poly_idx = order.polyOrder[poly_order_idx];
PolygonRef poly = skirt[poly_idx];
gcode.writeMove(poly[order.polyStart[poly_idx]], getSettingInMillimetersPerSecond("speed_travel"), 0);
for (unsigned int point_idx = 0; point_idx < poly.size(); point_idx++)
{
Point& p = poly[(point_idx + order.polyStart[poly_idx] + 1) % poly.size()];
gcode.writeMove(p, getSettingInMillimetersPerSecond("skirt_brim_speed"), getSettingInMillimeters("skirt_brim_line_width") * INT2MM(initial_layer_thickness));
}
}
}
void Wireframe2gcode::finalize()
{
gcode.finalize(getSettingString("machine_end_gcode").c_str());
for(int e=0; e<getSettingAsCount("machine_extruder_count"); e++)
gcode.writeTemperatureCommand(e, 0, false);
}
}//namespace cura
+170
Ver Arquivo
@@ -0,0 +1,170 @@
#ifndef WIREFRAME2GCODE_H
#define WIREFRAME2GCODE_H
#include <functional> // passing function pointer or lambda as argument to a function
#include "utils/NoCopy.h"
#include "weaveDataStorage.h"
#include "commandSocket.h"
#include "settings/settings.h"
#include "MeshGroup.h"
#include "slicer.h"
#include "utils/polygon.h"
#include "Weaver.h"
namespace cura
{
/*!
* Export class for exporting wireframe print gcode / weaver gcode / wireprint gcode.
*/
class Wireframe2gcode : public SettingsMessenger, NoCopy
{
private:
static const int STRATEGY_COMPENSATE = 0;
static const int STRATEGY_KNOT = 1;
static const int STRATEGY_RETRACT = 2;
int initial_layer_thickness;
int filament_diameter;
int line_width;
double flowConnection;
double flowFlat;
double extrusion_mm3_per_mm_connection;
double extrusion_mm3_per_mm_flat;
int nozzle_outer_diameter;
int nozzle_head_distance;
double nozzle_expansion_angle;
int nozzle_clearance;
int nozzle_top_diameter;
double moveSpeed;
double speedBottom;
double speedUp;
double speedDown;
double speedFlat;
int connectionHeight;
int roof_inset;
double flat_delay;
double bottom_delay;
double top_delay;
int up_dist_half_speed;
int top_jump_dist;
int fall_down;
int drag_along;
int strategy;
double go_back_to_last_top;
int straight_first_when_going_down;
int roof_fall_down;
int roof_drag_along;
double roof_outer_delay;
RetractionConfig standard_retraction_config; //!< The standard retraction settings used for moves between parts etc.
public:
GCodeExport& gcode; //!< Where the result is 'stored'
Wireframe2gcode(Weaver& weaver, GCodeExport& gcode, SettingsBase* settings_base);
void writeGCode();
private:
WireFrame& wireFrame;
/*!
* Startup gcode: nozzle temp up, retraction settings, bed temp
*/
void processStartingCode();
/*!
* Lay down a skirt
*/
void processSkirt();
/*!
* End gcode: nozzle temp down
*/
void finalize();
void writeFill(std::vector<WeaveRoofPart>& infill_insets, Polygons& outlines
, std::function<void (Wireframe2gcode& thiss, WeaveRoofPart& inset, WeaveConnectionPart& part, unsigned int segment_idx)> connectionHandler
, std::function<void (Wireframe2gcode& thiss, WeaveConnectionSegment& p)> flatHandler);
/*!
* Function for writing the gcode for a diagonally down movement of a connection.
*
* \param layer The layer in which the segment is
* \param part The part in which the segment is
* \param segment_idx The index of the segment in the \p part
*/
void go_down(WeaveLayer& layer, WeaveConnectionPart& part, unsigned int segment_idx);
/*!
* Function for writing the gcode of an upward move of a connection, which does a couple of small moves at the top.
*
* \param layer The layer in which the segment is
* \param part The part in which the segment is
* \param segment_idx The index of the segment in the \p part
*/
void strategy_knot(WeaveLayer& layer, WeaveConnectionPart& part, unsigned int segment_idx);
/*!
* Function for writing the gcode of an upward move of a connection, which does a retract at the top.
*
* \param layer The layer in which the segment is
* \param part The part in which the segment is
* \param segment_idx The index of the segment in the \p part
*/
void strategy_retract(WeaveLayer& layer, WeaveConnectionPart& part, unsigned int segment_idx);
/*!
* Function for writing the gcode of an upward move of a connection, which goes Wireframe2gcode::fall_down further up
* and Wireframe2gcode::drag_along back from the direction it will go to next.
*
* \param layer The layer in which the segment is
* \param part The part in which the segment is
* \param segment_idx The index of the segment in the \p part
*/
void strategy_compensate(WeaveLayer& layer, WeaveConnectionPart& part, unsigned int segment_idx);
/*!
* Function writing the gcode of a segment in the connection between two layers.
*
* \param layer The layer in which the segment is
* \param part The part in which the segment is
* \param segment_idx The index of the segment in the \p part
*/
void handle_segment(WeaveLayer& layer, WeaveConnectionPart& part, unsigned int segment_idx);
/*!
* Function for writing the gcode of a segment in the connection between two roof insets / floor outsets.
*
* \param inset The inset in which the segment is
* \param part the part in which the segment is
* \param segment_idx The index of the segment in the \p part
*/
void handle_roof_segment(WeaveRoofPart& inset, WeaveConnectionPart& part, unsigned int segment_idx);
/*!
* Write a move action to gcode, inserting a retraction if neccesary.
*
* \param to The 3D destination of the move
*/
void writeMoveWithRetract(Point3 to);
/*!
* Write a move action to gcode, inserting a retraction if neccesary.
*
* \param to The 2D destination of the move
*/
void writeMoveWithRetract(Point to);
};
}//namespace cura
#endif//WIREFRAME2GCODE_H
+2
Ver Arquivo
@@ -1,6 +1,8 @@
/** Copyright (C) 2013 David Braam - Released under terms of the AGPLv3 License */
#include "bridge.h"
#include "sliceDataStorage.h"
namespace cura {
int bridgeAngle(Polygons outline, SliceLayer* prevLayer)
+2 -2
Ver Arquivo
@@ -2,9 +2,9 @@
#ifndef BRIDGE_H
#define BRIDGE_H
#include "sliceDataStorage.h"
namespace cura {
class Polygons;
class SliceLayer;
int bridgeAngle(Polygons outline, SliceLayer* prevLayer);
-237
Ver Arquivo
@@ -1,237 +0,0 @@
/** Copyright (C) 2013 David Braam - Released under terms of the AGPLv3 License */
#include "comb.h"
namespace cura {
bool Comb::preTest(Point startPoint, Point endPoint)
{
return collisionTest(startPoint, endPoint);
}
bool Comb::collisionTest(Point startPoint, Point endPoint)
{
Point diff = endPoint - startPoint;
matrix = PointMatrix(diff);
sp = matrix.apply(startPoint);
ep = matrix.apply(endPoint);
for(unsigned int n=0; n<boundery.size(); n++)
{
if (boundery[n].size() < 1)
continue;
Point p0 = matrix.apply(boundery[n][boundery[n].size()-1]);
for(unsigned int i=0; i<boundery[n].size(); i++)
{
Point p1 = matrix.apply(boundery[n][i]);
if ((p0.Y > sp.Y && p1.Y < sp.Y) || (p1.Y > sp.Y && p0.Y < sp.Y))
{
int64_t x = p0.X + (p1.X - p0.X) * (sp.Y - p0.Y) / (p1.Y - p0.Y);
if (x > sp.X && x < ep.X)
return true;
}
p0 = p1;
}
}
return false;
}
void Comb::calcMinMax()
{
for(unsigned int n=0; n<boundery.size(); n++)
{
minX[n] = INT64_MAX;
maxX[n] = INT64_MIN;
Point p0 = matrix.apply(boundery[n][boundery[n].size()-1]);
for(unsigned int i=0; i<boundery[n].size(); i++)
{
Point p1 = matrix.apply(boundery[n][i]);
if ((p0.Y > sp.Y && p1.Y < sp.Y) || (p1.Y > sp.Y && p0.Y < sp.Y))
{
int64_t x = p0.X + (p1.X - p0.X) * (sp.Y - p0.Y) / (p1.Y - p0.Y);
if (x >= sp.X && x <= ep.X)
{
if (x < minX[n]) { minX[n] = x; minIdx[n] = i; }
if (x > maxX[n]) { maxX[n] = x; maxIdx[n] = i; }
}
}
p0 = p1;
}
}
}
unsigned int Comb::getPolygonAbove(int64_t x)
{
int64_t min = POINT_MAX;
unsigned int ret = NO_INDEX;
for(unsigned int n=0; n<boundery.size(); n++)
{
if (minX[n] > x && minX[n] < min)
{
min = minX[n];
ret = n;
}
}
return ret;
}
Point Comb::getBounderyPointWithOffset(unsigned int polygonNr, unsigned int idx)
{
Point p0 = boundery[polygonNr][(idx > 0) ? (idx - 1) : (boundery[polygonNr].size() - 1)];
Point p1 = boundery[polygonNr][idx];
Point p2 = boundery[polygonNr][(idx < (boundery[polygonNr].size() - 1)) ? (idx + 1) : (0)];
Point off0 = crossZ(normal(p1 - p0, MM2INT(1.0)));
Point off1 = crossZ(normal(p2 - p1, MM2INT(1.0)));
Point n = normal(off0 + off1, MM2INT(0.2));
return p1 + n;
}
Comb::Comb(Polygons& _boundery)
: boundery(_boundery)
{
minX = new int64_t[boundery.size()];
maxX = new int64_t[boundery.size()];
minIdx = new unsigned int[boundery.size()];
maxIdx = new unsigned int[boundery.size()];
}
Comb::~Comb()
{
delete[] minX;
delete[] maxX;
delete[] minIdx;
delete[] maxIdx;
}
bool Comb::moveInside(Point* p, int distance)
{
Point ret = *p;
int64_t bestDist = MM2INT(2.0) * MM2INT(2.0);
for(unsigned int n=0; n<boundery.size(); n++)
{
if (boundery[n].size() < 1)
continue;
Point p0 = boundery[n][boundery[n].size()-1];
for(unsigned int i=0; i<boundery[n].size(); i++)
{
Point p1 = boundery[n][i];
//Q = A + Normal( B - A ) * ((( B - A ) dot ( P - A )) / VSize( A - B ));
Point pDiff = p1 - p0;
int64_t lineLength = vSize(pDiff);
int64_t distOnLine = dot(pDiff, *p - p0) / lineLength;
if (distOnLine < 10)
distOnLine = 10;
if (distOnLine > lineLength - 10)
distOnLine = lineLength - 10;
Point q = p0 + pDiff * distOnLine / lineLength;
int64_t dist = vSize2(q - *p);
if (dist < bestDist)
{
bestDist = dist;
ret = q + crossZ(normal(p1 - p0, distance));
}
p0 = p1;
}
}
if (bestDist < MM2INT(2.0) * MM2INT(2.0))
{
*p = ret;
return true;
}
return false;
}
bool Comb::calc(Point startPoint, Point endPoint, vector<Point>& combPoints)
{
if (shorterThen(endPoint - startPoint, MM2INT(1.5)))
return true;
bool addEndpoint = false;
//Check if we are inside the comb boundaries
if (!boundery.inside(startPoint))
{
if (!moveInside(&startPoint)) //If we fail to move the point inside the comb boundary we need to retract.
return false;
combPoints.push_back(startPoint);
}
if (!boundery.inside(endPoint))
{
if (!moveInside(&endPoint)) //If we fail to move the point inside the comb boundary we need to retract.
return false;
addEndpoint = true;
}
//Check if we are crossing any bounderies, and pre-calculate some values.
if (!preTest(startPoint, endPoint))
{
//We're not crossing any boundaries. So skip the comb generation.
if (!addEndpoint && combPoints.size() == 0) //Only skip if we didn't move the start and end point.
return true;
}
//Calculate the minimum and maximum positions where we cross the comb boundary
calcMinMax();
int64_t x = sp.X;
vector<Point> pointList;
//Now walk trough the crossings, for every boundary we cross, find the initial cross point and the exit point. Then add all the points in between
// to the pointList and continue with the next boundary we will cross, until there are no more boundaries to cross.
// This gives a path from the start to finish curved around the holes that it encounters.
while(true)
{
unsigned int n = getPolygonAbove(x);
if (n == NO_INDEX) break;
pointList.push_back(matrix.unapply(Point(minX[n] - MM2INT(0.2), sp.Y)));
if ( (minIdx[n] - maxIdx[n] + boundery[n].size()) % boundery[n].size() > (maxIdx[n] - minIdx[n] + boundery[n].size()) % boundery[n].size())
{
for(unsigned int i=minIdx[n]; i != maxIdx[n]; i = (i < boundery[n].size() - 1) ? (i + 1) : (0))
{
pointList.push_back(getBounderyPointWithOffset(n, i));
}
}else{
if (minIdx[n] == 0)
minIdx[n] = boundery[n].size() - 1;
else
minIdx[n]--;
if (maxIdx[n] == 0)
maxIdx[n] = boundery[n].size() - 1;
else
maxIdx[n]--;
for(unsigned int i=minIdx[n]; i != maxIdx[n]; i = (i > 0) ? (i - 1) : (boundery[n].size() - 1))
{
pointList.push_back(getBounderyPointWithOffset(n, i));
}
}
pointList.push_back(matrix.unapply(Point(maxX[n] + MM2INT(0.2), sp.Y)));
x = maxX[n];
}
pointList.push_back(endPoint);
//Optimize the pointList, skip each point we could already reach by not crossing a boundary. This smooths out the path and makes it skip any unneeded corners.
Point p0 = startPoint;
for(unsigned int n=1; n<pointList.size(); n++)
{
if (collisionTest(p0, pointList[n]))
{
if (collisionTest(p0, pointList[n-1]))
return false;
p0 = pointList[n-1];
combPoints.push_back(p0);
}
}
if (addEndpoint)
combPoints.push_back(endPoint);
return true;
}
}//namespace cura
-44
Ver Arquivo
@@ -1,44 +0,0 @@
/** Copyright (C) 2013 David Braam - Released under terms of the AGPLv3 License */
#ifndef COMB_H
#define COMB_H
#include "utils/polygon.h"
namespace cura {
class Comb
{
private:
Polygons& boundery;
int64_t* minX;
int64_t* maxX;
unsigned int* minIdx;
unsigned int* maxIdx;
PointMatrix matrix;
Point sp;
Point ep;
bool preTest(Point startPoint, Point endPoint);
bool collisionTest(Point startPoint, Point endPoint);
void calcMinMax();
unsigned int getPolygonAbove(int64_t x);
Point getBounderyPointWithOffset(unsigned int polygonNr, unsigned int idx);
public:
Comb(Polygons& _boundery);
~Comb();
bool inside(const Point p) { return boundery.inside(p); }
bool moveInside(Point* p, int distance = 100);
bool calc(Point startPoint, Point endPoint, vector<Point>& combPoints);
};
}//namespace cura
#endif//COMB_H
+827
Ver Arquivo
@@ -0,0 +1,827 @@
#include "utils/logoutput.h"
#include "commandSocket.h"
#include "FffProcessor.h"
#include "progress/Progress.h"
#include <thread>
#include <cinttypes>
#ifdef ARCUS
#include <Arcus/Socket.h>
#include <Arcus/SocketListener.h>
#include <Arcus/Error.h>
#endif
#include <string> // stoi
#ifdef _WIN32
#include <windows.h>
#endif
#define DEBUG_OUTPUT_OBJECT_STL_THROUGH_CERR(x)
// std::cerr << x;
namespace cura {
#define BYTES_PER_FLOAT 4
#define FLOATS_PER_VECTOR 3
#define VECTORS_PER_FACE 3
CommandSocket* CommandSocket::instance = nullptr; // instantiate instance
#ifdef ARCUS
class Listener : public Arcus::SocketListener
{
public:
void stateChanged(Arcus::SocketState::SocketState newState) override
{
}
void messageReceived() override
{
}
void error(const Arcus::Error & error) override
{
if (error.getErrorCode() == Arcus::ErrorCode::Debug)
{
log("%s\n", error.toString().c_str());
}
else
{
logError("%s\n", error.toString().c_str());
}
}
};
/*!
* A template structure used to store data to be sent to the front end.
*/
template <typename T>
class SliceDataStruct
{
SliceDataStruct(const SliceDataStruct&) = delete;
SliceDataStruct& operator=(const SliceDataStruct&) = delete;
public:
SliceDataStruct()
: sliced_objects(0)
, current_layer_count(0)
, current_layer_offset(0)
{ }
//! The number of sliced objects for this sliced object list
int sliced_objects;
int current_layer_count;//!< Number of layers for which data has been buffered in slice_data so far.
int current_layer_offset;//!< Offset to add to layer number for the current slice object when slicing one at a time.
std::unordered_map<int, std::shared_ptr<T>> slice_data;
};
class CommandSocket::Private
{
public:
Private()
: socket(nullptr)
, object_count(0)
{ }
std::shared_ptr<cura::proto::Layer> getLayerById(int id);
std::shared_ptr<cura::proto::LayerOptimized> getOptimizedLayerById(int id);
Arcus::Socket* socket;
// Number of objects that need to be sliced
int object_count;
std::string temp_gcode_file;
std::ostringstream gcode_output_stream;
// Print object that olds one or more meshes that need to be sliced.
std::vector< std::shared_ptr<MeshGroup> > objects_to_slice;
SliceDataStruct<cura::proto::Layer> sliced_layers;
SliceDataStruct<cura::proto::LayerOptimized> optimized_layers;
};
/*!
* PathCompiler buffers and prepares the sliced data to be sent to the front end and saves them in
* appropriate buffers
*/
class CommandSocket::PathCompiler
{
typedef cura::proto::PathSegment::PointType PointType;
static_assert(sizeof(PrintFeatureType) == 1, "To be compatible with the Cura frontend code PrintFeatureType needs to be of size 1");
//! Reference to the private data of the CommandSocket used to send the data to the front end.
CommandSocket::Private& _cs_private_data;
//! Keeps track of the current layer number being processed. If layer number is set to a different value, the current data is flushed to CommandSocket.
int _layer_nr;
int extruder;
PointType data_point_type;
std::vector<PrintFeatureType> line_types; //!< Line types for the line segments stored, the size of this vector is N.
std::vector<float> line_widths; //!< Line widths for the line segments stored, the size of this vector is N.
std::vector<float> points; //!< The points used to define the line segments, the size of this vector is D*(N+1) as each line segment is defined from one point to the next. D is the dimensionality of the point.
Point last_point;
PathCompiler(const PathCompiler&) = delete;
PathCompiler& operator=(const PathCompiler&) = delete;
public:
PathCompiler(CommandSocket::Private& cs_private_data):
_cs_private_data(cs_private_data),
_layer_nr(0),
extruder(0),
data_point_type(cura::proto::PathSegment::Point2D),
line_types(),
line_widths(),
points(),
last_point{0,0}
{}
~PathCompiler()
{
if (line_types.size())
{
flushPathSegments();
}
}
/*!
* Used to select which layer the following layer data is intended for.
*/
void setLayer(int new_layer_nr)
{
if (_layer_nr != new_layer_nr)
{
flushPathSegments();
_layer_nr = new_layer_nr;
}
}
/*!
* Returns the current layer which data is written to.
*/
int getLayer() const
{
return _layer_nr;
}
/*!
* Used to set which extruder will be used for printing the following layer data is intended for.
*/
void setExtruder(int new_extruder)
{
if (extruder != new_extruder)
{
flushPathSegments();
extruder = new_extruder;
}
}
/*!
* Special handling of the first point in an added line sequence.
* If the new sequence of lines does not start at the current end point
* of the path this jump is marked as PrintFeatureType::NoneType
*/
void handleInitialPoint(Point from)
{
if (points.size() == 0)
{
addPoint2D(from);
}
else if (from != last_point)
{
addLineSegment(PrintFeatureType::NoneType, from, 1.0);
}
}
/*!
* Transfers the currently buffered line segments to the
* CommandSocket layer message storage.
*/
void flushPathSegments();
/*!
* Move the current point of this path to \position.
*/
void setCurrentPosition(Point position)
{
handleInitialPoint(position);
}
/*!
* Adds a single line segment to the current path. The line segment added is from the current last point to point \p to
*/
void sendLineTo(PrintFeatureType print_feature_type, Point to, int width);
/*!
* Adds closed polygon to the current path
*/
void sendPolygon(PrintFeatureType print_feature_type, Polygon poly, int width);
private:
/*!
* Convert and add a point to the points buffer, each point being represented as two consecutive floats. All members adding a 2D point to the data should use this function.
*/
void addPoint2D(Point point)
{
points.push_back(INT2MM(point.X));
points.push_back(INT2MM(point.Y));
last_point = point;
}
/*!
* Implements the functionality of adding a single 2D line segment to the path data. All member functions adding a 2D line segment should use this functions.
*/
void addLineSegment(PrintFeatureType print_feature_type, Point point, int line_width)
{
addPoint2D(point);
line_types.push_back(print_feature_type);
line_widths.push_back(INT2MM(line_width));
}
};
#endif
CommandSocket::CommandSocket()
#ifdef ARCUS
: private_data(new Private)
, path_comp(new PathCompiler(*private_data))
#endif
{
#ifdef ARCUS
#endif
}
CommandSocket* CommandSocket::getInstance()
{
return instance;
}
void CommandSocket::instantiate()
{
instance = new CommandSocket();
}
bool CommandSocket::isInstantiated()
{
return instance != nullptr;
}
void CommandSocket::connect(const std::string& ip, int port)
{
#ifdef ARCUS
private_data->socket = new Arcus::Socket();
private_data->socket->addListener(new Listener());
//private_data->socket->registerMessageType(1, &Cura::ObjectList::default_instance());
private_data->socket->registerMessageType(&cura::proto::Slice::default_instance());
private_data->socket->registerMessageType(&cura::proto::Layer::default_instance());
private_data->socket->registerMessageType(&cura::proto::LayerOptimized::default_instance());
private_data->socket->registerMessageType(&cura::proto::Progress::default_instance());
private_data->socket->registerMessageType(&cura::proto::GCodeLayer::default_instance());
private_data->socket->registerMessageType(&cura::proto::PrintTimeMaterialEstimates::default_instance());
private_data->socket->registerMessageType(&cura::proto::SettingList::default_instance());
private_data->socket->registerMessageType(&cura::proto::GCodePrefix::default_instance());
private_data->socket->registerMessageType(&cura::proto::SlicingFinished::default_instance());
private_data->socket->registerMessageType(&cura::proto::SettingExtruder::default_instance());
private_data->socket->connect(ip, port);
log("Connecting to %s:%i\n", ip.c_str(), port);
while(private_data->socket->getState() != Arcus::SocketState::Connected && private_data->socket->getState() != Arcus::SocketState::Error)
{
std::this_thread::sleep_for(std::chrono::milliseconds(100));
}
log("Connected to %s:%i\n", ip.c_str(), port);
bool slice_another_time = true;
// Start & continue listening as long as socket is not closed and there is no error.
while(private_data->socket->getState() != Arcus::SocketState::Closed && private_data->socket->getState() != Arcus::SocketState::Error && slice_another_time)
{
// Actually start handling messages.
Arcus::MessagePtr message = private_data->socket->takeNextMessage();
/*
* handle a message which consists purely of a SettingList
cura::proto::SettingList* setting_list = dynamic_cast<cura::proto::SettingList*>(message.get());
if (setting_list)
{
handleSettingList(setting_list);
}
*/
/*
* handle a message which consists purely of an ObjectList
cura::proto::ObjectList* object_list = dynamic_cast<cura::proto::ObjectList*>(message.get());
if (object_list)
{
handleObjectList(object_list);
}
*/
// Handle the main Slice message
cura::proto::Slice* slice = dynamic_cast<cura::proto::Slice*>(message.get()); // See if the message is of the message type Slice; returns nullptr otherwise
if (slice)
{
logDebug("Received a Slice message\n");
const cura::proto::SettingList& global_settings = slice->global_settings();
for (auto setting : global_settings.settings())
{
FffProcessor::getInstance()->setSetting(setting.name(), setting.value());
}
// Reset object counts
private_data->object_count = 0;
for (auto object : slice->object_lists())
{
handleObjectList(&object, slice->extruders());
}
//For every object, set the extruder fallbacks from the limit_to_extruder.
for (const cura::proto::SettingExtruder setting_extruder : slice->limit_to_extruder())
{
const int32_t extruder_nr = setting_extruder.extruder(); //Implicit cast from Protobuf's int32 to normal int32.
for (std::shared_ptr<MeshGroup> meshgroup : private_data->objects_to_slice)
{
if (extruder_nr < 0 || extruder_nr >= meshgroup->getExtruderCount()) //We obtained an invalid value from the front-end. Ignore.
{
continue;
}
const ExtruderTrain* settings_base = meshgroup->getExtruderTrain(extruder_nr); //The extruder train that the setting should fall back to.
for (Mesh& mesh : meshgroup->meshes)
{
mesh.setSettingInheritBase(setting_extruder.name(), *settings_base);
}
}
}
logDebug("Done reading Slice message\n");
}
//If there is an object to slice, do so.
if (private_data->objects_to_slice.size())
{
int object_count = private_data->objects_to_slice.size();
logDebug("Slicing %i objects\n", object_count);
FffProcessor::getInstance()->resetMeshGroupNumber();
int i = 1;
for (auto object : private_data->objects_to_slice)
{
logDebug("Slicing object %i of %i\n", i, object_count);
if (!FffProcessor::getInstance()->processMeshGroup(object.get()))
{
logError("Slicing mesh group failed!");
}
i++;
}
logDebug("Done slicing objects\n");
private_data->objects_to_slice.clear();
FffProcessor::getInstance()->finalize();
flushGcode();
sendPrintTimeMaterialEstimates();
sendFinishedSlicing();
slice_another_time = false; // TODO: remove this when multiple slicing with CuraEngine is safe
//TODO: Support all-at-once/one-at-a-time printing
//private_data->processor->processModel(private_data->object_to_slice.get());
//private_data->object_to_slice.reset();
//private_data->processor->resetFileNumber();
//sendPrintTimeMaterialEstimates();
}
std::this_thread::sleep_for(std::chrono::milliseconds(250));
}
log("Closing connection\n");
private_data->socket->close();
#endif
}
#ifdef ARCUS
void CommandSocket::handleObjectList(cura::proto::ObjectList* list, const google::protobuf::RepeatedPtrField<cura::proto::Extruder> settings_per_extruder_train)
{
if (list->objects_size() <= 0)
{
return;
}
FMatrix3x3 matrix;
//private_data->object_count = 0;
//private_data->object_ids.clear();
private_data->objects_to_slice.push_back(std::make_shared<MeshGroup>(FffProcessor::getInstance()));
MeshGroup* meshgroup = private_data->objects_to_slice.back().get();
// load meshgroup settings
for (auto setting : list->settings())
{
meshgroup->setSetting(setting.name(), setting.value());
}
{ // load extruder settings
for (int extruder_nr = 0; extruder_nr < FffProcessor::getInstance()->getSettingAsCount("machine_extruder_count"); extruder_nr++)
{ // initialize remaining extruder trains and load the defaults
meshgroup->createExtruderTrain(extruder_nr); // create new extruder train objects or use already existing ones
}
for (auto extruder : settings_per_extruder_train)
{
int extruder_nr = extruder.id();
ExtruderTrain* train = meshgroup->getExtruderTrain(extruder_nr);
for (auto setting : extruder.settings().settings())
{
train->setSetting(setting.name(), setting.value());
}
}
}
for (auto object : list->objects())
{
int bytes_per_face = BYTES_PER_FLOAT * FLOATS_PER_VECTOR * VECTORS_PER_FACE;
int face_count = object.vertices().size() / bytes_per_face;
if (face_count <= 0)
{
logWarning("Got an empty mesh, ignoring it!");
continue;
}
DEBUG_OUTPUT_OBJECT_STL_THROUGH_CERR("solid Cura_out\n");
// Check to which extruder train this object belongs
int extruder_train_nr = 0; // assume extruder 0 if setting wasn't supplied
for (auto setting : object.settings())
{
if (setting.name() == "extruder_nr")
{
extruder_train_nr = std::stoi(setting.value());
break;
}
}
SettingsBase* extruder_train = meshgroup->getExtruderTrain(extruder_train_nr);
meshgroup->meshes.push_back(extruder_train); //Construct a new mesh (with the corresponding extruder train as settings parent object) and put it into MeshGroup's mesh list.
Mesh& mesh = meshgroup->meshes.back();
for (int i = 0; i < face_count; ++i)
{
//TODO: Apply matrix
std::string data = object.vertices().substr(i * bytes_per_face, bytes_per_face);
const FPoint3* float_vertices = reinterpret_cast<const FPoint3*>(data.data());
Point3 verts[3];
verts[0] = matrix.apply(float_vertices[0]);
verts[1] = matrix.apply(float_vertices[1]);
verts[2] = matrix.apply(float_vertices[2]);
mesh.addFace(verts[0], verts[1], verts[2]);
DEBUG_OUTPUT_OBJECT_STL_THROUGH_CERR(" facet normal -1 0 0\n");
DEBUG_OUTPUT_OBJECT_STL_THROUGH_CERR(" outer loop\n");
DEBUG_OUTPUT_OBJECT_STL_THROUGH_CERR(" vertex "<<INT2MM(verts[0].x) <<" " << INT2MM(verts[0].y) <<" " << INT2MM(verts[0].z) << "\n");
DEBUG_OUTPUT_OBJECT_STL_THROUGH_CERR(" vertex "<<INT2MM(verts[1].x) <<" " << INT2MM(verts[1].y) <<" " << INT2MM(verts[1].z) << "\n");
DEBUG_OUTPUT_OBJECT_STL_THROUGH_CERR(" vertex "<<INT2MM(verts[2].x) <<" " << INT2MM(verts[2].y) <<" " << INT2MM(verts[2].z) << "\n");
DEBUG_OUTPUT_OBJECT_STL_THROUGH_CERR(" endloop\n");
DEBUG_OUTPUT_OBJECT_STL_THROUGH_CERR(" endfacet\n");
}
DEBUG_OUTPUT_OBJECT_STL_THROUGH_CERR("endsolid Cura_out\n");
for (auto setting : object.settings())
{
mesh.setSetting(setting.name(), setting.value());
}
mesh.finish();
}
private_data->object_count++;
meshgroup->finalize();
}
#endif
void CommandSocket::sendOptimizedLayerInfo(int layer_nr, int32_t z, int32_t height)
{
#ifdef ARCUS
std::shared_ptr<cura::proto::LayerOptimized> layer = private_data->getOptimizedLayerById(layer_nr);
layer->set_height(z);
layer->set_thickness(height);
#endif
}
void CommandSocket::sendPolygons(PrintFeatureType type, const Polygons& polygons, int line_width)
{
#ifdef ARCUS
if (polygons.size() == 0)
{
return;
}
if (CommandSocket::isInstantiated())
{
auto& path_comp = CommandSocket::getInstance()->path_comp;
for (unsigned int i = 0; i < polygons.size(); ++i)
{
path_comp->sendPolygon(type, polygons[i], line_width);
}
}
#endif
}
void CommandSocket::sendPolygon(PrintFeatureType type, Polygon& polygon, int line_width)
{
#ifdef ARCUS
if (CommandSocket::isInstantiated())
{
auto& path_comp = CommandSocket::getInstance()->path_comp;
path_comp->sendPolygon(type, polygon, line_width);
}
#endif
}
void CommandSocket::sendLineTo(cura::PrintFeatureType type, Point to, int line_width)
{
#ifdef ARCUS
if (CommandSocket::isInstantiated())
{
auto& path_comp = CommandSocket::getInstance()->path_comp;
path_comp->sendLineTo(type, to, line_width);
}
#endif
}
void CommandSocket::setSendCurrentPosition(Point position)
{
#ifdef ARCUS
if (CommandSocket::isInstantiated())
{
auto& path_comp = CommandSocket::getInstance()->path_comp;
path_comp->setCurrentPosition(position);
}
#endif
}
void CommandSocket::setLayerForSend(int layer_nr)
{
#ifdef ARCUS
if (CommandSocket::isInstantiated())
{
auto& path_comp = CommandSocket::getInstance()->path_comp;
path_comp->setLayer(layer_nr);
}
#endif
}
void CommandSocket::setExtruderForSend(int extruder)
{
#ifdef ARCUS
if (CommandSocket::isInstantiated())
{
auto& path_comp = CommandSocket::getInstance()->path_comp;
path_comp->setExtruder(extruder);
}
#endif
}
void CommandSocket::sendProgress(float amount)
{
#ifdef ARCUS
auto message = std::make_shared<cura::proto::Progress>();
amount /= private_data->object_count;
amount += private_data->optimized_layers.sliced_objects * (1. / private_data->object_count);
message->set_amount(amount);
private_data->socket->sendMessage(message);
#endif
}
void CommandSocket::sendProgressStage(Progress::Stage stage)
{
// TODO
}
void CommandSocket::sendPrintTimeMaterialEstimates()
{
#ifdef ARCUS
logDebug("Sending print time and material estimates.\n");
auto message = std::make_shared<cura::proto::PrintTimeMaterialEstimates>();
message->set_time(FffProcessor::getInstance()->getTotalPrintTime());
int num_extruders = FffProcessor::getInstance()->getSettingAsCount("machine_extruder_count");
for (int extruder_nr (0); extruder_nr < num_extruders; ++extruder_nr)
{
cura::proto::MaterialEstimates* material_message = message->add_materialestimates();
material_message->set_id(extruder_nr);
material_message->set_material_amount(FffProcessor::getInstance()->getTotalFilamentUsed(extruder_nr));
}
private_data->socket->sendMessage(message);
logDebug("Done sending print time and material estimates.\n");
#endif
}
void CommandSocket::sendPrintMaterialForObject(int index, int extruder_nr, float print_time)
{
// socket.sendInt32(CMD_OBJECT_PRINT_MATERIAL);
// socket.sendInt32(12);
// socket.sendInt32(index);
// socket.sendInt32(extruder_nr);
// socket.sendFloat32(print_time);
}
void CommandSocket::sendLayerData()
{
#ifdef ARCUS
#endif
#ifdef ARCUS
auto& data = private_data->sliced_layers;
data.sliced_objects++;
data.current_layer_offset = data.current_layer_count;
// log("End sliced object called. Sending %d layers.", data.current_layer_count);
// Only send the data to the front end when all mesh groups have been processed.
if (data.sliced_objects >= private_data->object_count)
{
for (std::pair<const int, std::shared_ptr<cura::proto::Layer>> entry : data.slice_data) //Note: This is in no particular order!
{
private_data->socket->sendMessage(entry.second); //Send the actual layers.
}
data.sliced_objects = 0;
data.current_layer_count = 0;
data.current_layer_offset = 0;
data.slice_data.clear();
}
#endif
}
void CommandSocket::sendOptimizedLayerData()
{
#ifdef ARCUS
path_comp->flushPathSegments(); // make sure the last path segment has been flushed from the compiler
auto& data = private_data->optimized_layers;
data.sliced_objects++;
data.current_layer_offset = data.current_layer_count;
log("End sliced object called. Sending %d layers.", data.current_layer_count);
if (data.sliced_objects >= private_data->object_count)
{
for (std::pair<const int, std::shared_ptr<cura::proto::LayerOptimized>> entry : data.slice_data) //Note: This is in no particular order!
{
private_data->socket->sendMessage(entry.second); //Send the actual layers.
}
data.sliced_objects = 0;
data.current_layer_count = 0;
data.current_layer_offset = 0;
data.slice_data.clear();
}
#endif
}
void CommandSocket::sendFinishedSlicing()
{
#ifdef ARCUS
logDebug("Sending Slicing Finished message.\n");
std::shared_ptr<cura::proto::SlicingFinished> done_message = std::make_shared<cura::proto::SlicingFinished>();
private_data->socket->sendMessage(done_message);
logDebug("Done sending Slicing Finished message.\n");
#endif
}
void CommandSocket::beginGCode()
{
#ifdef ARCUS
FffProcessor::getInstance()->setTargetStream(&private_data->gcode_output_stream);
#endif
}
void CommandSocket::flushGcode()
{
#ifdef ARCUS
auto message = std::make_shared<cura::proto::GCodeLayer>();
message->set_data(private_data->gcode_output_stream.str());
private_data->socket->sendMessage(message);
private_data->gcode_output_stream.str("");
#endif
}
void CommandSocket::sendGCodePrefix(std::string prefix)
{
#ifdef ARCUS
auto message = std::make_shared<cura::proto::GCodePrefix>();
message->set_data(prefix);
private_data->socket->sendMessage(message);
#endif
}
#ifdef ARCUS
std::shared_ptr<cura::proto::Layer> CommandSocket::Private::getLayerById(int id)
{
id += sliced_layers.current_layer_offset;
auto itr = sliced_layers.slice_data.find(id);
std::shared_ptr<cura::proto::Layer> layer;
if (itr != sliced_layers.slice_data.end())
{
layer = itr->second;
}
else
{
layer = std::make_shared<cura::proto::Layer>();
layer->set_id(id);
sliced_layers.current_layer_count++;
sliced_layers.slice_data[id] = layer;
}
return layer;
}
#endif
#ifdef ARCUS
std::shared_ptr<cura::proto::LayerOptimized> CommandSocket::Private::getOptimizedLayerById(int id)
{
id += optimized_layers.current_layer_offset;
auto itr = optimized_layers.slice_data.find(id);
std::shared_ptr<cura::proto::LayerOptimized> layer;
if (itr != optimized_layers.slice_data.end())
{
layer = itr->second;
}
else
{
layer = std::make_shared<cura::proto::LayerOptimized>();
layer->set_id(id);
optimized_layers.current_layer_count++;
optimized_layers.slice_data[id] = layer;
}
return layer;
}
#endif
#ifdef ARCUS
void CommandSocket::PathCompiler::flushPathSegments()
{
if (line_types.size() > 0 && CommandSocket::isInstantiated())
{
std::shared_ptr<cura::proto::LayerOptimized> proto_layer = _cs_private_data.getOptimizedLayerById(_layer_nr);
cura::proto::PathSegment* p = proto_layer->add_path_segment();
p->set_extruder(extruder);
p->set_point_type(data_point_type);
std::string line_type_data;
line_type_data.append(reinterpret_cast<const char*>(line_types.data()), line_types.size()*sizeof(PrintFeatureType));
p->set_line_type(line_type_data);
std::string polydata;
polydata.append(reinterpret_cast<const char*>(points.data()), points.size() * sizeof(float));
p->set_points(polydata);
std::string line_width_data;
line_width_data.append(reinterpret_cast<const char*>(line_widths.data()), line_widths.size()*sizeof(float));
p->set_line_width(line_width_data);
}
points.clear();
line_widths.clear();
line_types.clear();
}
void CommandSocket::PathCompiler::sendLineTo(PrintFeatureType print_feature_type, Point to, int width)
{
assert(points.size() > 0 && "A point must already be in the buffer for sendLineTo(.) to function properly");
if (to != last_point)
{
addLineSegment(print_feature_type, to, width);
}
}
void CommandSocket::PathCompiler::sendPolygon(PrintFeatureType print_feature_type, Polygon polygon, int width)
{
if (polygon.size() < 2)
{
return;
}
auto it = polygon.begin();
handleInitialPoint(*it);
const auto it_end = polygon.end();
while (++it != it_end)
{
// Ignore zero-length segments.
if (*it != last_point)
{
addLineSegment(print_feature_type, *it, width);
}
}
// Make sure the polygon is closed
if (*polygon.begin() != polygon.back())
{
addLineSegment(print_feature_type, *polygon.begin(), width);
}
}
#endif
}//namespace cura
+158
Ver Arquivo
@@ -0,0 +1,158 @@
#ifndef COMMAND_SOCKET_H
#define COMMAND_SOCKET_H
#include "utils/socket.h"
#include "utils/polygon.h"
#include "settings/settings.h"
#include "progress/Progress.h"
#include "PrintFeature.h"
#include <memory>
#ifdef ARCUS
#include "Cura.pb.h"
#endif
namespace cura
{
class CommandSocket
{
private:
static CommandSocket* instance; //!< May be a nullptr in case it hasn't been instantiated.
CommandSocket(); //!< The single constructor is known only privately, since this class is similar to a singleton class (except the single object doesn't need to be instantiated)
public:
static CommandSocket* getInstance(); //!< Get the CommandSocket instance, or nullptr if it hasn't been instantiated.
static void instantiate(); //!< Instantiate the CommandSocket.
static bool isInstantiated(); //!< Check whether the singleton is instantiated
/*!
* Connect with the GUI
* This creates and initialises the arcus socket and then continues listening for messages.
* \param ip string containing the ip to connect with
* \param port int of the port to connect with.
*/
void connect(const std::string& ip, int port);
#ifdef ARCUS
/*!
* Handler for ObjectList message.
* Loads all objects from the message and starts the slicing process
*
* Also handles meshgroup settings and extruder settings.
*
* \param[in] list The list of objects to slice
* \param[in] settings_per_extruder_train The extruder train settings to load into the meshgroup
*/
void handleObjectList(cura::proto::ObjectList* list, const google::protobuf::RepeatedPtrField<cura::proto::Extruder> settings_per_extruder_train);
#endif
/*!
* Send info on an optimized layer to be displayed by the forntend: set the z and the thickness of the layer.
*/
void sendOptimizedLayerInfo(int layer_nr, int32_t z, int32_t height);
/*!
* Send a polygon to the front-end. This is used for the layerview in the GUI
*/
static void sendPolygons(cura::PrintFeatureType type, const cura::Polygons& polygons, int line_width);
/*!
* Send a polygon to the front-end. This is used for the layerview in the GUI
*/
static void sendPolygon(cura::PrintFeatureType type, Polygon& polygon, int line_width);
/*!
* Send a line to the front-end. This is used for the layerview in the GUI
*/
static void sendLineTo(cura::PrintFeatureType type, Point to, int line_width);
/*!
* Set the current position of the path compiler to \p position. This is used for the layerview in the GUI
*/
static void setSendCurrentPosition(Point position);
/*!
* Set which layer is being used for the following calls to SendPolygons, SendPolygon and SendLineTo.
*/
static void setLayerForSend(int layer_nr);
/*!
* Set which extruder is being used for the following calls to SendPolygons, SendPolygon and SendLineTo.
*/
static void setExtruderForSend(int extruder);
/*!
* Send a polygon to the front-end if the command socket is instantiated. This is used for the layerview in the GUI
*/
static void sendPolygonsToCommandSocket(cura::PrintFeatureType type, int layer_nr, const cura::Polygons& polygons, int line_width);
/*!
* Send progress to GUI
*/
void sendProgress(float amount);
/*!
* Send the current stage of the process to the GUI (starting, slicing infill, etc)
*/
void sendProgressStage(Progress::Stage stage);
/*!
* Send time estimate of how long print would take.
*/
void sendPrintTimeMaterialEstimates();
/*!
* Does nothing at the moment
*/
void sendPrintMaterialForObject(int index, int extruder_nr, float material_amount);
/*!
* Send the slices of the model as polygons to the GUI.
*
* The GUI may use this to visualize the early result of the slicing
* process.
*/
void sendLayerData();
/*!
* Send the sliced layer data to the GUI after the optimization is done and
* the actual order in which to print has been set.
*
* The GUI may use this to visualize the g-code, so that the user can
* inspect the result of slicing.
*/
void sendOptimizedLayerData();
/*!
* \brief Sends a message to indicate that all the slicing is done.
*
* This should indicate that no more data (g-code, prefix/postfix, metadata
* or otherwise) should be sent any more regarding the latest slice job.
*/
void sendFinishedSlicing();
void beginGCode();
/*!
* Flush the gcode in gcode_output_stream into a message queued in the socket.
*/
void flushGcode();
void sendGCodePrefix(std::string prefix);
#ifdef ARCUS
private:
class Private;
const std::unique_ptr<Private> private_data;
class PathCompiler;
const std::unique_ptr<PathCompiler> path_comp;
#endif
};
}//namespace cura
#endif//COMMAND_SOCKET_H
-770
Ver Arquivo
@@ -1,770 +0,0 @@
#ifndef FFF_PROCESSOR_H
#define FFF_PROCESSOR_H
#include <algorithm>
#include <vector>
#include "utils/socket.h"
#define GUI_CMD_REQUEST_MESH 0x01
#define GUI_CMD_SEND_POLYGONS 0x02
#define GUI_CMD_FINISH_OBJECT 0x03
namespace cura {
//FusedFilamentFabrication processor.
class fffProcessor
{
private:
int maxObjectHeight;
int fileNr;
GCodeExport gcode;
ConfigSettings& config;
TimeKeeper timeKeeper;
ClientSocket guiSocket;
GCodePathConfig skirtConfig;
GCodePathConfig inset0Config;
GCodePathConfig insetXConfig;
GCodePathConfig fillConfig;
GCodePathConfig supportConfig;
public:
fffProcessor(ConfigSettings& config)
: config(config)
{
fileNr = 1;
maxObjectHeight = 0;
}
void guiConnect(int portNr)
{
guiSocket.connectTo("127.0.0.1", portNr);
}
void sendPolygonsToGui(const char* name, int layerNr, int32_t z, Polygons& polygons)
{
guiSocket.sendNr(GUI_CMD_SEND_POLYGONS);
guiSocket.sendNr(polygons.size());
guiSocket.sendNr(layerNr);
guiSocket.sendNr(z);
guiSocket.sendNr(strlen(name));
guiSocket.sendAll(name, strlen(name));
for(unsigned int n=0; n<polygons.size(); n++)
{
PolygonRef polygon = polygons[n];
guiSocket.sendNr(polygon.size());
guiSocket.sendAll(polygon.data(), polygon.size() * sizeof(Point));
}
}
bool setTargetFile(const char* filename)
{
gcode.setFilename(filename);
if (gcode.isOpened())
gcode.writeComment("Generated with Cura_SteamEngine %s", VERSION);
return gcode.isOpened();
}
bool processFile(const std::vector<std::string> &files)
{
if (!gcode.isOpened())
return false;
TimeKeeper timeKeeperTotal;
SliceDataStorage storage;
preSetup();
if (!prepareModel(storage, files))
return false;
processSliceData(storage);
writeGCode(storage);
cura::logProgress("process", 1, 1);//Report the GUI that a file has been fully processed.
cura::log("Total time elapsed %5.2fs.\n", timeKeeperTotal.restart());
guiSocket.sendNr(GUI_CMD_FINISH_OBJECT);
return true;
}
void finalize()
{
if (!gcode.isOpened())
return;
gcode.finalize(maxObjectHeight, config.moveSpeed, config.endCode.c_str());
}
private:
void preSetup()
{
skirtConfig.setData(config.printSpeed, config.extrusionWidth, "SKIRT");
inset0Config.setData(config.inset0Speed, config.extrusionWidth, "WALL-OUTER");
insetXConfig.setData(config.insetXSpeed, config.extrusionWidth, "WALL-INNER");
fillConfig.setData(config.infillSpeed, config.extrusionWidth, "FILL");
supportConfig.setData(config.printSpeed, config.extrusionWidth, "SUPPORT");
for(unsigned int n=1; n<MAX_EXTRUDERS;n++)
gcode.setExtruderOffset(n, config.extruderOffset[n].p());
gcode.setSwitchExtruderCode(config.preSwitchExtruderCode, config.postSwitchExtruderCode);
gcode.setFlavor(config.gcodeFlavor);
gcode.setRetractionSettings(config.retractionAmount, config.retractionSpeed, config.retractionAmountExtruderSwitch, config.minimalExtrusionBeforeRetraction, config.retractionZHop, config.retractionAmountPrime);
}
bool prepareModel(SliceDataStorage& storage, const std::vector<std::string> &files)
{
timeKeeper.restart();
SimpleModel* model = nullptr;
if (files.size() == 1 && files[0][0] == '$')
{
const char *input_filename = files[0].c_str();
model = new SimpleModel();
for(unsigned int n=0; input_filename[n]; n++)
{
model->volumes.push_back(SimpleVolume());
SimpleVolume* volume = &model->volumes[model->volumes.size()-1];
guiSocket.sendNr(GUI_CMD_REQUEST_MESH);
int32_t vertexCount = guiSocket.recvNr();
int pNr = 0;
cura::log("Reading mesh from socket with %i vertexes\n", vertexCount);
Point3 v[3];
while(vertexCount)
{
float f[3];
guiSocket.recvAll(f, 3 * sizeof(float));
FPoint3 fp(f[0], f[1], f[2]);
v[pNr++] = config.matrix.apply(fp);
if (pNr == 3)
{
volume->addFace(v[0], v[1], v[2]);
pNr = 0;
}
vertexCount--;
}
}
}else{
model = new SimpleModel();
for(unsigned int i=0;i < files.size(); i++) {
if(files[i] == "-")
model->volumes.push_back(SimpleVolume());
else {
cura::log("Loading %s from disk...\n", files[i].c_str());
SimpleModel *test = loadModelFromFile(model,files[i].c_str(), config.matrix);
if(test == nullptr) { // error while reading occurred
cura::logError("Failed to load model: %s\n", files[i].c_str());
return false;
}
}
}
}
cura::log("Loaded from disk in %5.3fs\n", timeKeeper.restart());
cura::log("Analyzing and optimizing model...\n");
OptimizedModel* optimizedModel = new OptimizedModel(model, Point3(config.objectPosition.X, config.objectPosition.Y, -config.objectSink));
for(unsigned int v = 0; v < model->volumes.size(); v++)
{
cura::log(" Face counts: %i -> %i %0.1f%%\n", (int)model->volumes[v].faces.size(), (int)optimizedModel->volumes[v].faces.size(), float(optimizedModel->volumes[v].faces.size()) / float(model->volumes[v].faces.size()) * 100);
cura::log(" Vertex counts: %i -> %i %0.1f%%\n", (int)model->volumes[v].faces.size() * 3, (int)optimizedModel->volumes[v].points.size(), float(optimizedModel->volumes[v].points.size()) / float(model->volumes[v].faces.size() * 3) * 100);
cura::log(" Size: %f %f %f\n", INT2MM(optimizedModel->modelSize.x), INT2MM(optimizedModel->modelSize.y), INT2MM(optimizedModel->modelSize.z));
cura::log(" vMin: %f %f %f\n", INT2MM(optimizedModel->vMin.x), INT2MM(optimizedModel->vMin.y), INT2MM(optimizedModel->vMin.z));
cura::log(" vMax: %f %f %f\n", INT2MM(optimizedModel->vMax.x), INT2MM(optimizedModel->vMax.y), INT2MM(optimizedModel->vMax.z));
cura::log(" vMin: %f %f %f\n", INT2MM(model->min().x), INT2MM(model->min().y), INT2MM(model->min().z));
cura::log(" vMax: %f %f %f\n", INT2MM(model->max().x), INT2MM(model->max().y), INT2MM(model->max().z));
cura::log(" Matrix: %f %f %f\n", config.matrix.m[0][0], config.matrix.m[1][0], config.matrix.m[2][0]);
cura::log(" Matrix: %f %f %f\n", config.matrix.m[0][1], config.matrix.m[1][1], config.matrix.m[2][1]);
cura::log(" Matrix: %f %f %f\n", config.matrix.m[0][2], config.matrix.m[1][2], config.matrix.m[2][2]);
if (INT2MM(optimizedModel->modelSize.x) > 10000.0 || INT2MM(optimizedModel->modelSize.y) > 10000.0 || INT2MM(optimizedModel->modelSize.z) > 10000.0)
{
cura::logError("Object is way to big, CuraEngine bug?");
exit(1);
}
}
delete model;
cura::log("Optimize model %5.3fs \n", timeKeeper.restart());
//om->saveDebugSTL("c:\\models\\output.stl");
cura::log("Slicing model...\n");
vector<Slicer*> slicerList;
for(unsigned int volumeIdx=0; volumeIdx < optimizedModel->volumes.size(); volumeIdx++)
{
Slicer* slicer = new Slicer(&optimizedModel->volumes[volumeIdx], config.initialLayerThickness - config.layerThickness / 2, config.layerThickness, config.fixHorrible & FIX_HORRIBLE_KEEP_NONE_CLOSED, config.fixHorrible & FIX_HORRIBLE_EXTENSIVE_STITCHING);
slicerList.push_back(slicer);
for(unsigned int layerNr=0; layerNr<slicer->layers.size(); layerNr++)
{
//Reporting the outline here slows down the engine quite a bit, so only do so when debugging.
//sendPolygonsToGui("outline", layerNr, slicer->layers[layerNr].z, slicer->layers[layerNr].polygonList);
sendPolygonsToGui("openoutline", layerNr, slicer->layers[layerNr].z, slicer->layers[layerNr].openPolygonList);
}
}
cura::log("Sliced model in %5.3fs\n", timeKeeper.restart());
cura::log("Generating support map...\n");
generateSupportGrid(storage.support, optimizedModel, config.supportAngle, config.supportEverywhere > 0, config.supportXYDistance, config.supportZDistance);
storage.modelSize = optimizedModel->modelSize;
storage.modelMin = optimizedModel->vMin;
storage.modelMax = optimizedModel->vMax;
delete optimizedModel;
cura::log("Generating layer parts...\n");
for(unsigned int volumeIdx=0; volumeIdx < slicerList.size(); volumeIdx++)
{
storage.volumes.push_back(SliceVolumeStorage());
createLayerParts(storage.volumes[volumeIdx], slicerList[volumeIdx], config.fixHorrible & (FIX_HORRIBLE_UNION_ALL_TYPE_A | FIX_HORRIBLE_UNION_ALL_TYPE_B | FIX_HORRIBLE_UNION_ALL_TYPE_C));
delete slicerList[volumeIdx];
//Add the raft offset to each layer.
for(unsigned int layerNr=0; layerNr<storage.volumes[volumeIdx].layers.size(); layerNr++)
storage.volumes[volumeIdx].layers[layerNr].printZ += config.raftBaseThickness + config.raftInterfaceThickness;
}
cura::log("Generated layer parts in %5.3fs\n", timeKeeper.restart());
return true;
}
void processSliceData(SliceDataStorage& storage)
{
const unsigned int totalLayers = storage.volumes[0].layers.size();
//carveMultipleVolumes(storage.volumes);
generateMultipleVolumesOverlap(storage.volumes, config.multiVolumeOverlap);
//dumpLayerparts(storage, "c:/models/output.html");
if (config.simpleMode)
{
for(unsigned int layerNr=0; layerNr<totalLayers; layerNr++)
{
for(unsigned int volumeIdx=0; volumeIdx<storage.volumes.size(); volumeIdx++)
{
SliceLayer* layer = &storage.volumes[volumeIdx].layers[layerNr];
for(unsigned int partNr=0; partNr<layer->parts.size(); partNr++)
{
sendPolygonsToGui("inset0", layerNr, layer->printZ, layer->parts[partNr].outline);
}
}
}
return;
}
for(unsigned int layerNr=0; layerNr<totalLayers; layerNr++)
{
for(unsigned int volumeIdx=0; volumeIdx<storage.volumes.size(); volumeIdx++)
{
int insetCount = config.insetCount;
if (config.spiralizeMode && static_cast<int>(layerNr) < config.downSkinCount && layerNr % 2 == 1)//Add extra insets every 2 layers when spiralizing, this makes bottoms of cups watertight.
insetCount += 5;
SliceLayer* layer = &storage.volumes[volumeIdx].layers[layerNr];
int extrusionWidth = config.extrusionWidth;
if (layerNr == 0)
extrusionWidth = config.layer0extrusionWidth;
generateInsets(layer, extrusionWidth, insetCount);
for(unsigned int partNr=0; partNr<layer->parts.size(); partNr++)
{
if (layer->parts[partNr].insets.size() > 0)
{
sendPolygonsToGui("inset0", layerNr, layer->printZ, layer->parts[partNr].insets[0]);
for(unsigned int inset=1; inset<layer->parts[partNr].insets.size(); inset++)
sendPolygonsToGui("insetx", layerNr, layer->printZ, layer->parts[partNr].insets[inset]);
}
}
}
cura::logProgress("inset",layerNr+1,totalLayers);
}
if (config.enableOozeShield)
{
for(unsigned int layerNr=0; layerNr<totalLayers; layerNr++)
{
Polygons oozeShield;
for(unsigned int volumeIdx=0; volumeIdx<storage.volumes.size(); volumeIdx++)
{
for(unsigned int partNr=0; partNr<storage.volumes[volumeIdx].layers[layerNr].parts.size(); partNr++)
{
oozeShield = oozeShield.unionPolygons(storage.volumes[volumeIdx].layers[layerNr].parts[partNr].outline.offset(MM2INT(2.0)));
}
}
storage.oozeShield.push_back(oozeShield);
}
for(unsigned int layerNr=0; layerNr<totalLayers; layerNr++)
storage.oozeShield[layerNr] = storage.oozeShield[layerNr].offset(-MM2INT(1.0)).offset(MM2INT(1.0));
int offsetAngle = tan(60.0*M_PI/180) * config.layerThickness;//Allow for a 60deg angle in the oozeShield.
for(unsigned int layerNr=1; layerNr<totalLayers; layerNr++)
storage.oozeShield[layerNr] = storage.oozeShield[layerNr].unionPolygons(storage.oozeShield[layerNr-1].offset(-offsetAngle));
for(unsigned int layerNr=totalLayers-1; layerNr>0; layerNr--)
storage.oozeShield[layerNr-1] = storage.oozeShield[layerNr-1].unionPolygons(storage.oozeShield[layerNr].offset(-offsetAngle));
}
cura::log("Generated inset in %5.3fs\n", timeKeeper.restart());
for(unsigned int layerNr=0; layerNr<totalLayers; layerNr++)
{
if (!config.spiralizeMode || static_cast<int>(layerNr) < config.downSkinCount) //Only generate up/downskin and infill for the first X layers when spiralize is choosen.
{
for(unsigned int volumeIdx=0; volumeIdx<storage.volumes.size(); volumeIdx++)
{
int extrusionWidth = config.extrusionWidth;
if (layerNr == 0)
extrusionWidth = config.layer0extrusionWidth;
generateSkins(layerNr, storage.volumes[volumeIdx], extrusionWidth, config.downSkinCount, config.upSkinCount, config.infillOverlap);
generateSparse(layerNr, storage.volumes[volumeIdx], extrusionWidth, config.downSkinCount, config.upSkinCount);
SliceLayer* layer = &storage.volumes[volumeIdx].layers[layerNr];
for(unsigned int partNr=0; partNr<layer->parts.size(); partNr++)
sendPolygonsToGui("skin", layerNr, layer->printZ, layer->parts[partNr].skinOutline);
}
}
cura::logProgress("skin",layerNr+1,totalLayers);
}
cura::log("Generated up/down skin in %5.3fs\n", timeKeeper.restart());
if (config.wipeTowerSize > 0)
{
PolygonRef p = storage.wipeTower.newPoly();
p.add(Point(storage.modelMin.x - 3000, storage.modelMax.y + 3000));
p.add(Point(storage.modelMin.x - 3000, storage.modelMax.y + 3000 + config.wipeTowerSize));
p.add(Point(storage.modelMin.x - 3000 - config.wipeTowerSize, storage.modelMax.y + 3000 + config.wipeTowerSize));
p.add(Point(storage.modelMin.x - 3000 - config.wipeTowerSize, storage.modelMax.y + 3000));
storage.wipePoint = Point(storage.modelMin.x - 3000 - config.wipeTowerSize / 2, storage.modelMax.y + 3000 + config.wipeTowerSize / 2);
}
if (config.raftBaseThickness > 0 && config.raftInterfaceThickness > 0)
generateSkirt(storage, config.raftMargin + config.raftBaseLinewidth, config.raftBaseLinewidth, config.skirtLineCount, config.skirtMinLength, config.raftBaseThickness);
else
generateSkirt(storage, config.skirtDistance, config.layer0extrusionWidth, config.skirtLineCount, config.skirtMinLength, config.initialLayerThickness);
generateRaft(storage, config.raftMargin);
sendPolygonsToGui("skirt", 0, config.initialLayerThickness, storage.skirt);
}
void writeGCode(SliceDataStorage& storage)
{
if (fileNr == 1)
{
if (gcode.getFlavor() == GCODE_FLAVOR_ULTIGCODE)
{
gcode.writeComment("FLAVOR:UltiGCode");
gcode.writeComment("TIME:<__TIME__>");
gcode.writeComment("MATERIAL:<FILAMENT>");
gcode.writeComment("MATERIAL2:<FILAMEN2>");
}
gcode.writeCode(config.startCode.c_str());
if (gcode.getFlavor() == GCODE_FLAVOR_BFB)
{
gcode.writeComment("enable auto-retraction");
gcode.writeLine("M227 S%d P%d", config.retractionAmount * 2560 / 1000, config.retractionAmount * 2560 / 1000);
}
}else{
gcode.writeFanCommand(0);
gcode.resetExtrusionValue();
gcode.writeRetraction();
gcode.setZ(maxObjectHeight + 5000);
gcode.writeMove(gcode.getPositionXY(), config.moveSpeed, 0);
gcode.writeMove(Point(storage.modelMin.x, storage.modelMin.y), config.moveSpeed, 0);
}
fileNr++;
unsigned int totalLayers = storage.volumes[0].layers.size();
gcode.writeComment("Layer count: %d", totalLayers);
if (config.raftBaseThickness > 0 && config.raftInterfaceThickness > 0)
{
sendPolygonsToGui("support", 0, config.raftBaseThickness, storage.raftOutline);
sendPolygonsToGui("support", 0, config.raftBaseThickness + config.raftInterfaceThickness, storage.raftOutline);
GCodePathConfig raftBaseConfig((config.raftBaseSpeed <= 0) ? config.initialLayerSpeed : config.raftBaseSpeed, config.raftBaseLinewidth, "SUPPORT");
GCodePathConfig raftMiddleConfig(config.printSpeed, config.raftInterfaceLinewidth, "SUPPORT");
GCodePathConfig raftInterfaceConfig(config.printSpeed, config.raftInterfaceLinewidth, "SUPPORT");
GCodePathConfig raftSurfaceConfig((config.raftSurfaceSpeed > 0) ? config.raftSurfaceSpeed : config.printSpeed, config.raftSurfaceLinewidth, "SUPPORT");
{
gcode.writeComment("LAYER:-2");
gcode.writeComment("RAFT");
GCodePlanner gcodeLayer(gcode, config.moveSpeed, config.retractionMinimalDistance);
if (config.supportExtruder > 0)
gcodeLayer.setExtruder(config.supportExtruder);
gcode.setZ(config.raftBaseThickness);
gcode.setExtrusion(config.raftBaseThickness, config.filamentDiameter, config.filamentFlow);
gcodeLayer.addPolygonsByOptimizer(storage.skirt, &raftBaseConfig);
gcodeLayer.addPolygonsByOptimizer(storage.raftOutline, &raftBaseConfig);
Polygons raftLines;
generateLineInfill(storage.raftOutline, raftLines, config.raftBaseLinewidth, config.raftLineSpacing, config.infillOverlap, 0);
gcodeLayer.addPolygonsByOptimizer(raftLines, &raftBaseConfig);
gcodeLayer.writeGCode(false, config.raftBaseThickness);
}
if (config.raftFanSpeed) {
gcode.writeFanCommand(config.raftFanSpeed);
}
{
gcode.writeComment("LAYER:-1");
gcode.writeComment("RAFT");
GCodePlanner gcodeLayer(gcode, config.moveSpeed, config.retractionMinimalDistance);
gcode.setZ(config.raftBaseThickness + config.raftInterfaceThickness);
gcode.setExtrusion(config.raftInterfaceThickness, config.filamentDiameter, config.filamentFlow);
Polygons raftLines;
generateLineInfill(storage.raftOutline, raftLines, config.raftInterfaceLinewidth, config.raftInterfaceLineSpacing, config.infillOverlap, config.raftSurfaceLayers > 0 ? 45 : 90);
gcodeLayer.addPolygonsByOptimizer(raftLines, &raftInterfaceConfig);
gcodeLayer.writeGCode(false, config.raftInterfaceThickness);
}
for (int raftSurfaceLayer=1; raftSurfaceLayer<=config.raftSurfaceLayers; raftSurfaceLayer++)
{
gcode.writeComment("LAYER:-1");
gcode.writeComment("RAFT");
GCodePlanner gcodeLayer(gcode, config.moveSpeed, config.retractionMinimalDistance);
gcode.setZ(config.raftBaseThickness + config.raftInterfaceThickness + config.raftSurfaceThickness*raftSurfaceLayer);
gcode.setExtrusion(config.raftSurfaceThickness, config.filamentDiameter, config.filamentFlow);
Polygons raftLines;
generateLineInfill(storage.raftOutline, raftLines, config.raftSurfaceLinewidth, config.raftSurfaceLineSpacing, config.infillOverlap, 90 * raftSurfaceLayer);
gcodeLayer.addPolygonsByOptimizer(raftLines, &raftSurfaceConfig);
gcodeLayer.writeGCode(false, config.raftInterfaceThickness);
}
}
int volumeIdx = 0;
for(unsigned int layerNr=0; layerNr<totalLayers; layerNr++)
{
cura::logProgress("export", layerNr+1, totalLayers);
int extrusionWidth = config.extrusionWidth;
if (layerNr == 0)
extrusionWidth = config.layer0extrusionWidth;
if (static_cast<int>(layerNr) < config.initialSpeedupLayers)
{
int n = config.initialSpeedupLayers;
#define SPEED_SMOOTH(speed) \
std::min<int>((speed), (((speed)*layerNr)/n + (config.initialLayerSpeed*(n-layerNr)/n)))
skirtConfig.setData(SPEED_SMOOTH(config.printSpeed), extrusionWidth, "SKIRT");
inset0Config.setData(SPEED_SMOOTH(config.inset0Speed), extrusionWidth, "WALL-OUTER");
insetXConfig.setData(SPEED_SMOOTH(config.insetXSpeed), extrusionWidth, "WALL-INNER");
fillConfig.setData(SPEED_SMOOTH(config.infillSpeed), extrusionWidth, "FILL");
supportConfig.setData(SPEED_SMOOTH(config.printSpeed), extrusionWidth, "SUPPORT");
#undef SPEED_SMOOTH
}else{
skirtConfig.setData(config.printSpeed, extrusionWidth, "SKIRT");
inset0Config.setData(config.inset0Speed, extrusionWidth, "WALL-OUTER");
insetXConfig.setData(config.insetXSpeed, extrusionWidth, "WALL-INNER");
fillConfig.setData(config.infillSpeed, extrusionWidth, "FILL");
supportConfig.setData(config.printSpeed, extrusionWidth, "SUPPORT");
}
gcode.writeComment("LAYER:%d", layerNr);
if (layerNr == 0)
gcode.setExtrusion(config.initialLayerThickness, config.filamentDiameter, config.filamentFlow);
else
gcode.setExtrusion(config.layerThickness, config.filamentDiameter, config.filamentFlow);
GCodePlanner gcodeLayer(gcode, config.moveSpeed, config.retractionMinimalDistance);
int32_t z = config.initialLayerThickness + layerNr * config.layerThickness;
z += config.raftBaseThickness + config.raftInterfaceThickness + config.raftSurfaceLayers*config.raftSurfaceThickness;
if (config.raftBaseThickness > 0 && config.raftInterfaceThickness > 0)
{
if (layerNr == 0)
{
z += config.raftAirGapLayer0;
} else {
z += config.raftAirGap;
}
}
gcode.setZ(z);
bool printSupportFirst = (storage.support.generated && config.supportExtruder > 0 && config.supportExtruder == gcodeLayer.getExtruder());
if (printSupportFirst)
addSupportToGCode(storage, gcodeLayer, layerNr);
for(unsigned int volumeCnt = 0; volumeCnt < storage.volumes.size(); volumeCnt++)
{
if (volumeCnt > 0)
volumeIdx = (volumeIdx + 1) % storage.volumes.size();
addVolumeLayerToGCode(storage, gcodeLayer, volumeIdx, layerNr);
}
if (!printSupportFirst)
addSupportToGCode(storage, gcodeLayer, layerNr);
//Finish the layer by applying speed corrections for minimal layer times
gcodeLayer.forceMinimalLayerTime(config.minimalLayerTime, config.minimalFeedrate);
int fanSpeed = config.fanSpeedMin;
if (gcodeLayer.getExtrudeSpeedFactor() <= 50)
{
fanSpeed = config.fanSpeedMax;
}else{
int n = gcodeLayer.getExtrudeSpeedFactor() - 50;
fanSpeed = config.fanSpeedMin * n / 50 + config.fanSpeedMax * (50 - n) / 50;
}
if (static_cast<int>(layerNr) < config.fanFullOnLayerNr)
{
//Slow down the fan on the layers below the [fanFullOnLayerNr], where layer 0 is speed 0.
fanSpeed = fanSpeed * layerNr / config.fanFullOnLayerNr;
}
gcode.writeFanCommand(fanSpeed);
gcodeLayer.writeGCode(config.coolHeadLift > 0, static_cast<int>(layerNr) > 0 ? config.layerThickness : config.initialLayerThickness);
}
cura::log("Wrote layers in %5.2fs.\n", timeKeeper.restart());
gcode.tellFileSize();
gcode.writeFanCommand(0);
//Store the object height for when we are printing multiple objects, as we need to clear every one of them when moving to the next position.
maxObjectHeight = std::max(maxObjectHeight, storage.modelSize.z - config.objectSink);
}
//Add a single layer from a single mesh-volume to the GCode
void addVolumeLayerToGCode(SliceDataStorage& storage, GCodePlanner& gcodeLayer, int volumeIdx, int layerNr)
{
int prevExtruder = gcodeLayer.getExtruder();
bool extruderChanged = gcodeLayer.setExtruder(volumeIdx);
if (layerNr == 0 && volumeIdx == 0 && !(config.raftBaseThickness > 0 && config.raftInterfaceThickness > 0))
{
if (storage.skirt.size() > 0)
gcodeLayer.addTravel(storage.skirt[storage.skirt.size()-1].closestPointTo(gcode.getPositionXY()));
gcodeLayer.addPolygonsByOptimizer(storage.skirt, &skirtConfig);
}
SliceLayer* layer = &storage.volumes[volumeIdx].layers[layerNr];
if (extruderChanged)
addWipeTower(storage, gcodeLayer, layerNr, prevExtruder);
if (storage.oozeShield.size() > 0 && storage.volumes.size() > 1)
{
gcodeLayer.setAlwaysRetract(true);
gcodeLayer.addPolygonsByOptimizer(storage.oozeShield[layerNr], &skirtConfig);
sendPolygonsToGui("oozeshield", layerNr, layer->printZ, storage.oozeShield[layerNr]);
gcodeLayer.setAlwaysRetract(!config.enableCombing);
}
if (config.simpleMode)
{
Polygons polygons;
for(unsigned int partNr=0; partNr<layer->parts.size(); partNr++)
{
for(unsigned int n=0; n<layer->parts[partNr].outline.size(); n++)
{
for(unsigned int m=1; m<layer->parts[partNr].outline[n].size(); m++)
{
Polygon p;
p.add(layer->parts[partNr].outline[n][m-1]);
p.add(layer->parts[partNr].outline[n][m]);
polygons.add(p);
}
if (layer->parts[partNr].outline[n].size() > 0)
{
Polygon p;
p.add(layer->parts[partNr].outline[n][layer->parts[partNr].outline[n].size()-1]);
p.add(layer->parts[partNr].outline[n][0]);
polygons.add(p);
}
}
}
for(unsigned int n=0; n<layer->openLines.size(); n++)
{
for(unsigned int m=1; m<layer->openLines[n].size(); m++)
{
Polygon p;
p.add(layer->openLines[n][m-1]);
p.add(layer->openLines[n][m]);
polygons.add(p);
}
}
if (config.spiralizeMode)
inset0Config.spiralize = true;
gcodeLayer.addPolygonsByOptimizer(polygons, &inset0Config);
return;
}
PathOrderOptimizer partOrderOptimizer(gcode.getPositionXY());
for(unsigned int partNr=0; partNr<layer->parts.size(); partNr++)
{
partOrderOptimizer.addPolygon(layer->parts[partNr].insets[0][0]);
}
partOrderOptimizer.optimize();
for(unsigned int partCounter=0; partCounter<partOrderOptimizer.polyOrder.size(); partCounter++)
{
SliceLayerPart* part = &layer->parts[partOrderOptimizer.polyOrder[partCounter]];
if (config.enableCombing)
gcodeLayer.setCombBoundary(&part->combBoundery);
else
gcodeLayer.setAlwaysRetract(true);
if (config.insetCount > 0)
{
if (config.spiralizeMode)
{
if (static_cast<int>(layerNr) >= config.downSkinCount)
inset0Config.spiralize = true;
if (static_cast<int>(layerNr) == config.downSkinCount && part->insets.size() > 0)
gcodeLayer.addPolygonsByOptimizer(part->insets[0], &insetXConfig);
}
for(int insetNr=part->insets.size()-1; insetNr>-1; insetNr--)
{
if (insetNr == 0)
gcodeLayer.addPolygonsByOptimizer(part->insets[insetNr], &inset0Config);
else
gcodeLayer.addPolygonsByOptimizer(part->insets[insetNr], &insetXConfig);
}
}
Polygons fillPolygons;
int fillAngle = 45;
if (layerNr & 1)
fillAngle += 90;
int extrusionWidth = config.extrusionWidth;
if (layerNr == 0)
extrusionWidth = config.layer0extrusionWidth;
for(Polygons outline : part->skinOutline.splitIntoParts())
{
int bridge = -1;
if (layerNr > 0)
bridge = bridgeAngle(outline, &storage.volumes[volumeIdx].layers[layerNr-1]);
generateLineInfill(outline, fillPolygons, extrusionWidth, extrusionWidth, config.infillOverlap, (bridge > -1) ? bridge : fillAngle);
}
if (config.sparseInfillLineDistance > 0)
{
switch (config.infillPattern)
{
case INFILL_AUTOMATIC:
generateAutomaticInfill(
part->sparseOutline, fillPolygons, extrusionWidth,
config.sparseInfillLineDistance,
config.infillOverlap, fillAngle);
break;
case INFILL_GRID:
generateGridInfill(part->sparseOutline, fillPolygons,
extrusionWidth,
config.sparseInfillLineDistance,
config.infillOverlap, fillAngle);
break;
case INFILL_LINES:
generateLineInfill(part->sparseOutline, fillPolygons,
extrusionWidth,
config.sparseInfillLineDistance,
config.infillOverlap, fillAngle);
break;
case INFILL_CONCENTRIC:
generateConcentricInfill(
part->sparseOutline, fillPolygons,
config.sparseInfillLineDistance);
break;
}
}
gcodeLayer.addPolygonsByOptimizer(fillPolygons, &fillConfig);
//sendPolygonsToGui("infill", layerNr, layer->z, fillPolygons);
//After a layer part, make sure the nozzle is inside the comb boundary, so we do not retract on the perimeter.
if (!config.spiralizeMode || static_cast<int>(layerNr) < config.downSkinCount)
gcodeLayer.moveInsideCombBoundary(config.extrusionWidth * 2);
}
gcodeLayer.setCombBoundary(nullptr);
}
void addSupportToGCode(SliceDataStorage& storage, GCodePlanner& gcodeLayer, int layerNr)
{
if (!storage.support.generated)
return;
if (config.supportExtruder > -1)
{
int prevExtruder = gcodeLayer.getExtruder();
if (gcodeLayer.setExtruder(config.supportExtruder))
addWipeTower(storage, gcodeLayer, layerNr, prevExtruder);
if (storage.oozeShield.size() > 0 && storage.volumes.size() == 1)
{
gcodeLayer.setAlwaysRetract(true);
gcodeLayer.addPolygonsByOptimizer(storage.oozeShield[layerNr], &skirtConfig);
gcodeLayer.setAlwaysRetract(!config.enableCombing);
}
}
int32_t z = config.initialLayerThickness + layerNr * config.layerThickness;
SupportPolyGenerator supportGenerator(storage.support, z);
for(unsigned int volumeCnt = 0; volumeCnt < storage.volumes.size(); volumeCnt++)
{
SliceLayer* layer = &storage.volumes[volumeCnt].layers[layerNr];
for(unsigned int n=0; n<layer->parts.size(); n++)
supportGenerator.polygons = supportGenerator.polygons.difference(layer->parts[n].outline.offset(config.supportXYDistance));
}
//Contract and expand the suppory polygons so small sections are removed and the final polygon is smoothed a bit.
supportGenerator.polygons = supportGenerator.polygons.offset(-config.extrusionWidth * 3);
supportGenerator.polygons = supportGenerator.polygons.offset(config.extrusionWidth * 3);
sendPolygonsToGui("support", layerNr, z, supportGenerator.polygons);
vector<Polygons> supportIslands = supportGenerator.polygons.splitIntoParts();
PathOrderOptimizer islandOrderOptimizer(gcode.getPositionXY());
for(unsigned int n=0; n<supportIslands.size(); n++)
{
islandOrderOptimizer.addPolygon(supportIslands[n][0]);
}
islandOrderOptimizer.optimize();
for(unsigned int n=0; n<supportIslands.size(); n++)
{
Polygons& island = supportIslands[islandOrderOptimizer.polyOrder[n]];
Polygons supportLines;
if (config.supportLineDistance > 0)
{
switch(config.supportType)
{
case SUPPORT_TYPE_GRID:
if (config.supportLineDistance > config.extrusionWidth * 4)
{
generateLineInfill(island, supportLines, config.extrusionWidth, config.supportLineDistance*2, config.infillOverlap, 0);
generateLineInfill(island, supportLines, config.extrusionWidth, config.supportLineDistance*2, config.infillOverlap, 90);
}else{
generateLineInfill(island, supportLines, config.extrusionWidth, config.supportLineDistance, config.infillOverlap, (layerNr & 1) ? 0 : 90);
}
break;
case SUPPORT_TYPE_LINES:
if (layerNr == 0)
{
generateLineInfill(island, supportLines, config.extrusionWidth, config.supportLineDistance, config.infillOverlap + 150, 0);
generateLineInfill(island, supportLines, config.extrusionWidth, config.supportLineDistance, config.infillOverlap + 150, 90);
}else{
generateLineInfill(island, supportLines, config.extrusionWidth, config.supportLineDistance, config.infillOverlap, 0);
}
break;
}
}
gcodeLayer.forceRetract();
if (config.enableCombing)
gcodeLayer.setCombBoundary(&island);
if (config.supportType == SUPPORT_TYPE_GRID)
gcodeLayer.addPolygonsByOptimizer(island, &supportConfig);
gcodeLayer.addPolygonsByOptimizer(supportLines, &supportConfig);
gcodeLayer.setCombBoundary(nullptr);
}
}
void addWipeTower(SliceDataStorage& storage, GCodePlanner& gcodeLayer, int layerNr, int prevExtruder)
{
if (config.wipeTowerSize < 1)
return;
//If we changed extruder, print the wipe/prime tower for this nozzle;
gcodeLayer.addPolygonsByOptimizer(storage.wipeTower, &supportConfig);
Polygons fillPolygons;
generateLineInfill(storage.wipeTower, fillPolygons, config.extrusionWidth, config.extrusionWidth, config.infillOverlap, 45 + 90 * (layerNr % 2));
gcodeLayer.addPolygonsByOptimizer(fillPolygons, &supportConfig);
//Make sure we wipe the old extruder on the wipe tower.
gcodeLayer.addTravel(storage.wipePoint - config.extruderOffset[prevExtruder].p() + config.extruderOffset[gcodeLayer.getExtruder()].p());
}
};
}//namespace cura
#endif//FFF_PROCESSOR_H
+807 -571
Ver Arquivo
Diferenças do arquivo suprimidas por serem muito extensas Carregar Diff
+325 -179
Ver Arquivo
@@ -3,228 +3,374 @@
#define GCODEEXPORT_H
#include <stdio.h>
#include <deque> // for extrusionAmountAtPreviousRetractions
#include <sstream> // for stream.str()
#include "settings.h"
#include "comb.h"
#include "settings/settings.h"
#include "utils/intpoint.h"
#include "utils/polygon.h"
#include "utils/NoCopy.h"
#include "timeEstimate.h"
#include "MeshGroup.h"
#include "commandSocket.h"
#include "RetractionConfig.h"
namespace cura {
/*!
* Coasting configuration used during printing.
* Can differ per extruder.
*
* Might be used in the future to have different coasting per feature, e.g. outer wall only.
*/
struct CoastingConfig
{
bool coasting_enable; //!< Whether coasting is enabled on the extruder to which this config is attached
double coasting_volume; //!< The volume leeked when printing without feeding
double coasting_speed; //!< A modifier (0-1) on the last used travel speed to move slower during coasting
double coasting_min_volume; //!< The minimal volume printed to build up enough pressure to leek the coasting_volume
};
//The GCodeExport class writes the actual GCode. This is the only class that knows how GCode looks and feels.
// Any customizations on GCodes flavors are done in this class.
class GCodeExport
class GCodeExport : public NoCopy
{
private:
FILE* f;
double extrusionAmount;
double extrusionPerMM;
double retractionAmount;
double retractionAmountPrime;
int retractionZHop;
double extruderSwitchRetraction;
double minimalExtrusionBeforeRetraction;
double extrusionAmountAtPreviousRetraction;
struct ExtruderTrainAttributes
{
Point3 prime_pos; //!< The location this nozzle is primed before printing
bool prime_pos_is_abs; //!< Whether the prime position is absolute, rather than relative to the last given position
bool is_primed; //!< Whether this extruder has currently already been primed in this print
bool is_used; //!< Whether this extruder train is actually used during the printing of all meshgroups
int nozzle_size; //!< The nozzle size label of the nozzle (e.g. 0.4mm; irrespective of tolerances)
Point nozzle_offset;
char extruderCharacter;
std::string material_guid; //!< The GUID for the material used by this extruder
std::string start_code;
std::string end_code;
double filament_area; //!< in mm^2 for non-volumetric, cylindrical filament
double totalFilament; //!< total filament used per extruder in mm^3
int currentTemperature;
int initial_temp; //!< Temperature this nozzle needs to be at the start of the print.
double retraction_e_amount_current; //!< The current retracted amount (in mm or mm^3), or zero(i.e. false) if it is not currently retracted (positive values mean retracted amount, so negative impact on E values)
double retraction_e_amount_at_e_start; //!< The ExtruderTrainAttributes::retraction_amount_current value at E0, i.e. the offset (in mm or mm^3) from E0 to the situation where the filament is at the tip of the nozzle.
double prime_volume; //!< Amount of material (in mm^3) to be primed after an unretration (due to oozing and/or coasting)
double last_retraction_prime_speed; //!< The last prime speed (in mm/s) of the to-be-primed amount
std::deque<double> extruded_volume_at_previous_n_retractions; // in mm^3
ExtruderTrainAttributes()
: prime_pos(0, 0, 0)
, prime_pos_is_abs(false)
, is_primed(false)
, is_used(false)
, nozzle_offset(0,0)
, extruderCharacter(0)
, start_code("")
, end_code("")
, filament_area(0)
, totalFilament(0)
, currentTemperature(0)
, initial_temp(0)
, retraction_e_amount_current(0.0)
, retraction_e_amount_at_e_start(0.0)
, prime_volume(0.0)
, last_retraction_prime_speed(0.0)
{ }
};
ExtruderTrainAttributes extruder_attr[MAX_EXTRUDERS];
unsigned int extruder_count;
bool use_extruder_offset_to_offset_coords;
Point3 machine_dimensions;
std::string machine_name;
std::ostream* output_stream;
std::string new_line;
double current_e_value; //!< The last E value written to gcode (in mm or mm^3)
Point3 currentPosition;
Point extruderOffset[MAX_EXTRUDERS];
char extruderCharacter[MAX_EXTRUDERS];
int currentSpeed, retractionSpeed;
int zPos;
bool isRetracted;
int extruderNr;
double currentSpeed; //!< The current speed (F values / 60) in mm/s
double current_acceleration; //!< The current acceleration in the XY direction (in mm/s^2)
double current_jerk; //!< The current jerk in the XY direction (in mm/s^3)
double current_max_z_feedrate; //!< The current max z speed
AABB3D total_bounding_box; //!< The bounding box of all g-code.
/*!
* The z position to be used on the next xy move, if the head wasn't in the correct z position yet.
*
* \see GCodeExport::writeMove(Point, double, double)
*
* \note After GCodeExport::writeMove(Point, double, double) has been called currentPosition.z coincides with this value
*/
int current_layer_z;
int isZHopped; //!< The amount by which the print head is currently z hopped, or zero if it is not z hopped. (A z hop is used during travel moves to avoid collision with other layer parts)
int current_extruder;
int currentFanSpeed;
int flavor;
std::string preSwitchExtruderCode;
std::string postSwitchExtruderCode;
double totalFilament[MAX_EXTRUDERS];
double totalPrintTime;
EGCodeFlavor flavor;
double totalPrintTime; //!< The total estimated print time in seconds
TimeEstimateCalculator estimateCalculator;
bool is_volumatric;
bool firmware_retract; //!< whether retractions are done in the firmware, or hardcoded in E values.
unsigned int layer_nr; //!< for sending travel data
int initial_bed_temp; //!< bed temperature at the beginning of the print.
protected:
/*!
* Convert an E value to a value in mm (if it wasn't already in mm) for the current extruder.
*
* E values are either in mm or in mm^3
* The current extruder is used to determine the filament area to make the conversion.
*
* \param e the value to convert
* \return the value converted to mm
*/
double eToMm(double e);
/*!
* Convert a volume value to an E value (which might be volumetric as well) for the current extruder.
*
* E values are either in mm or in mm^3
* The current extruder is used to determine the filament area to make the conversion.
*
* \param mm3 the value to convert
* \return the value converted to mm or mm3 depending on whether the E axis is volumetric
*/
double mm3ToE(double mm3);
/*!
* Convert a distance value to an E value (which might be linear/distance based as well) for the current extruder.
*
* E values are either in mm or in mm^3
* The current extruder is used to determine the filament area to make the conversion.
*
* \param mm the value to convert
* \return the value converted to mm or mm3 depending on whether the E axis is volumetric
*/
double mmToE(double mm);
public:
GCodeExport();
~GCodeExport();
/*!
* Get the gcode file header (e.g. ";FLAVOR:UltiGCode\n")
*
* \param print_time The total print time in seconds of the whole gcode (if known)
* \param filament_used The total mm^3 filament used for each extruder or a vector of the wrong size of unknown
* \param mat_ids The material GUIDs for each material.
* \return The string representing the file header
*/
std::string getFileHeader(const double* print_time = nullptr, const std::vector<double>& filament_used = std::vector<double>(), const std::vector<std::string>& mat_ids = std::vector<std::string>());
void setLayerNr(unsigned int layer_nr);
void replaceTagInStart(const char* tag, const char* replaceValue);
void setOutputStream(std::ostream* stream);
bool getExtruderIsUsed(const int extruder_nr) const; //!< Returns whether the extruder with the given index is used up until the current meshgroup
int getNozzleSize(const int extruder_nr) const;
Point getExtruderOffset(const int id) const;
std::string getMaterialGUID(const int extruder_nr) const; //!< returns the GUID of the material used for the nozzle with id \p extruder_nr
Point getGcodePos(const int64_t x, const int64_t y, const int extruder_train) const;
void setExtruderOffset(int id, Point p);
void setSwitchExtruderCode(std::string preSwitchExtruderCode, std::string postSwitchExtruderCode);
void setFlavor(int flavor);
int getFlavor();
void setFilename(const char* filename);
bool isOpened();
void setExtrusion(int layerThickness, int filamentDiameter, int flow);
void setRetractionSettings(int retractionAmount, int retractionSpeed, int extruderSwitchRetraction, int minimalExtrusionBeforeRetraction, int zHop, int retractionAmountPrime);
void setFlavor(EGCodeFlavor flavor);
EGCodeFlavor getFlavor();
void setZ(int z);
Point getPositionXY();
void addLastCoastedVolume(double last_coasted_volume)
{
extruder_attr[current_extruder].prime_volume += last_coasted_volume;
}
Point3 getPosition();
Point getPositionXY();
int getPositionZ();
int getExtruderNr();
double getTotalFilamentUsed(int e);
void setFilamentDiameter(unsigned int n, int diameter);
double getCurrentExtrudedVolume();
/*!
* Get the total extruded volume for a specific extruder in mm^3
*
* Retractions and unretractions don't contribute to this.
*
* \param extruder_nr The extruder number for which to get the total netto extruded volume
* \return total filament printed in mm^3
*/
double getTotalFilamentUsed(int extruder_nr);
/*!
* Get the total estimated print time in seconds
*
* \return total print time in seconds
*/
double getTotalPrintTime();
void updateTotalPrintTime();
void resetTotalPrintTimeAndFilament();
void writeComment(const char* comment, ...);
void writeComment(std::string comment);
void writeTypeComment(PrintFeatureType type);
void writeLine(const char* line, ...);
/*!
* Write a comment saying what (estimated) time has passed up to this point
*
* \param time The time passed up till this point
*/
void writeTimeComment(const double time);
void writeLayerComment(int layer_nr);
void writeLayerCountComment(int layer_count);
void writeLine(const char* line);
/*!
* Reset the current_e_value to prevent too high E values.
*
* The current extruded volume is added to the current extruder_attr.
*/
void resetExtrusionValue();
void writeDelay(double timeAmount);
void writeMove(Point p, int speed, int lineWidth);
void writeRetraction(bool force=false);
void switchExtruder(int newExtruder);
void writeMove(Point p, double speed, double extrusion_mm3_per_mm);
void writeMove(Point3 p, double speed, double extrusion_mm3_per_mm);
private:
void writeMove(int x, int y, int z, double speed, double extrusion_mm3_per_mm);
/*!
* The writeMove when flavor == BFB
*/
void writeMoveBFB(int x, int y, int z, double speed, double extrusion_mm3_per_mm);
public:
void writeRetraction(RetractionConfig* config, bool force = false, bool extruder_switch = false);
/*!
* Start a z hop with the given \p hop_height
*
* \param hop_height The height to move above the current layer
*/
void writeZhopStart(int hop_height);
/*!
* End a z hop: go back to the layer height
*
*/
void writeZhopEnd();
/*!
* Start the new_extruder:
* - set new extruder
* - zero E value
* - write extruder start gcode
*
* \param new_extruder The extruder to start with
*/
void startExtruder(int new_extruder);
/*!
* Switch to the new_extruder:
* - perform neccesary retractions
* - fiddle with E-values
* - write extruder end gcode
* - set new extruder
* - write extruder start gcode
*
* \param new_extruder The extruder to switch to
* \param retraction_config_old_extruder The extruder switch retraction config of the old extruder, to perform the extruder switch retraction with.
*/
void switchExtruder(int new_extruder, const RetractionConfig& retraction_config_old_extruder);
void writeCode(const char* str);
void writeFanCommand(int speed);
/*!
* Write the gcode for priming the current extruder train so that it can be used.
*
* \param travel_speed The travel speed when priming involves a movement
*/
void writePrimeTrain(double travel_speed);
void finalize(int maxObjectHeight, int moveSpeed, const char* endCode);
void writeFanCommand(double speed);
void writeTemperatureCommand(int extruder, double temperature, bool wait = false);
void writeBedTemperatureCommand(double temperature, bool wait = false);
/*!
* Write the command for setting the acceleration to a specific value
*/
void writeAcceleration(double acceleration);
/*!
* Write the command for setting the jerk to a specific value
*/
void writeJerk(double jerk);
/*!
* Write the command for setting the maximum z feedrate to a specific value
*/
void writeMaxZFeedrate(double max_z_feedrate);
/*!
* Get the last set max z feedrate value sent in the gcode.
*
* Returns a value <= 0 when no value is set.
*/
double getCurrentMaxZFeedrate();
/*!
* Set member variables using the settings in \p settings
*
* \param settings The meshgroup to get the global bed temp from and to get the extruder trains from which to get the nozzle temperatures
*/
void preSetup(const MeshGroup* settings);
/*!
* Handle the initial (bed/nozzle) temperatures before any gcode is processed.
* These temperatures are set in the pre-print setup in the firmware.
*
* See FffGcodeWriter::processStartingCode
*
* \param settings The meshgroup to get the global bed temp from and to get the extruder trains from which to get the nozzle temperatures
*/
void setInitialTemps(const MeshGroup& settings);
/*!
* Override or set an initial nozzle temperature as written by GCodeExport::setInitialTemps
* This is used primarily during better specification of temperatures in LayerPlanBuffer::insertPreheatCommand
*
* \param extruder_nr The extruder number for which to better specify the temp
* \param temp The temp at which the nozzle should be at startup
*/
void setInitialTemp(int extruder_nr, double temp);
/*!
* Finish the gcode: turn fans off, write end gcode and flush all gcode left in the buffer.
*
* \param endCode The end gcode to be appended at the very end.
*/
void finalize(const char* endCode);
int getFileSize();
void tellFileSize();
};
//The GCodePathConfig is the configuration for moves/extrusion actions. This defines at which width the line is printed and at which speed.
class GCodePathConfig
{
public:
int speed;
int lineWidth;
const char* name;
bool spiralize;
GCodePathConfig() : speed(0), lineWidth(0), name(nullptr), spiralize(false) {}
GCodePathConfig(int speed, int lineWidth, const char* name) : speed(speed), lineWidth(lineWidth), name(name), spiralize(false) {}
void setData(int speed, int lineWidth, const char* name)
{
this->speed = speed;
this->lineWidth = lineWidth;
this->name = name;
}
};
class GCodePath
{
public:
GCodePathConfig* config;
bool retract;
int extruder;
vector<Point> points;
bool done;//Path is finished, no more moves should be added, and a new path should be started instead of any appending done to this one.
};
//The GCodePlanner class stores multiple moves that are planned.
// It facilitates the combing to keep the head inside the print.
// It also keeps track of the print time estimate for this planning so speed adjustments can be made for the minimal-layer-time.
class GCodePlanner
{
private:
GCodeExport& gcode;
Point lastPosition;
vector<GCodePath> paths;
Comb* comb;
GCodePathConfig travelConfig;
int extrudeSpeedFactor;
int travelSpeedFactor;
int currentExtruder;
int retractionMinimalDistance;
bool forceRetraction;
bool alwaysRetract;
double extraTime;
double totalPrintTime;
private:
GCodePath* getLatestPathWithConfig(GCodePathConfig* config);
void forceNewPathStart();
public:
GCodePlanner(GCodeExport& gcode, int travelSpeed, int retractionMinimalDistance);
~GCodePlanner();
bool setExtruder(int extruder)
{
if (extruder == currentExtruder)
return false;
currentExtruder = extruder;
return true;
}
int getExtruder()
{
return currentExtruder;
}
void setCombBoundary(Polygons* polygons)
{
if (comb)
delete comb;
if (polygons)
comb = new Comb(*polygons);
else
comb = nullptr;
}
void setAlwaysRetract(bool alwaysRetract)
{
this->alwaysRetract = alwaysRetract;
}
void forceRetract()
{
forceRetraction = true;
}
void setExtrudeSpeedFactor(int speedFactor)
{
if (speedFactor < 1) speedFactor = 1;
this->extrudeSpeedFactor = speedFactor;
}
int getExtrudeSpeedFactor()
{
return this->extrudeSpeedFactor;
}
void setTravelSpeedFactor(int speedFactor)
{
if (speedFactor < 1) speedFactor = 1;
this->travelSpeedFactor = speedFactor;
}
int getTravelSpeedFactor()
{
return this->travelSpeedFactor;
}
void addTravel(Point p);
void addExtrusionMove(Point p, GCodePathConfig* config);
void moveInsideCombBoundary(int distance);
void addPolygon(PolygonRef polygon, int startIdx, GCodePathConfig* config);
void addPolygonsByOptimizer(Polygons& polygons, GCodePathConfig* config);
void forceMinimalLayerTime(double minTime, int minimalSpeed);
void writeGCode(bool liftHeadIfNeeded, int layerThickness);
};
}//namespace cura
}
#endif//GCODEEXPORT_H
Diferenças do arquivo suprimidas por serem muito extensas Carregar Diff
+725
Ver Arquivo
@@ -0,0 +1,725 @@
/** Copyright (C) 2016 Ultimaker - Released under terms of the AGPLv3 License */
#ifndef GCODE_PLANNER_H
#define GCODE_PLANNER_H
#include <vector>
#include "gcodeExport.h"
#include "pathPlanning/Comb.h"
#include "utils/polygon.h"
#include "utils/logoutput.h"
#include "wallOverlap.h"
#include "commandSocket.h"
#include "FanSpeedLayerTime.h"
#include "SpaceFillType.h"
#include "GCodePathConfig.h"
#include "utils/optional.h"
namespace cura
{
class SliceDataStorage;
class SliceLayerPart;
/*!
* A gcode command to insert before a specific path.
*
* Currently only used for preheat commands
*/
struct NozzleTempInsert
{
const unsigned int path_idx; //!< The path before which to insert this command
double time_after_path_start; //!< The time after the start of the path, before which to insert the command // TODO: use this to insert command in between moves in a path!
int extruder; //!< The extruder for which to set the temp
double temperature; //!< The temperature of the temperature command to insert
bool wait; //!< Whether to wait for the temperature to be reached
NozzleTempInsert(unsigned int path_idx, int extruder, double temperature, bool wait, double time_after_path_start = 0.0)
: path_idx(path_idx)
, time_after_path_start(time_after_path_start)
, extruder(extruder)
, temperature(temperature)
, wait(wait)
{
assert(temperature != 0 && temperature != -1 && "Temperature command must be set!");
}
/*!
* Write the temperature command at the current position in the gcode.
* \param gcode The actual gcode writer
*/
void write(GCodeExport& gcode)
{
gcode.writeTemperatureCommand(extruder, temperature, wait);
}
};
class ExtruderPlan; // forward declaration so that TimeMaterialEstimates can be a friend
/*!
* Time and material estimates for a portion of paths, e.g. layer, extruder plan, path.
*/
class TimeMaterialEstimates
{
friend class ExtruderPlan; // cause there the naive estimates are calculated
private:
double extrude_time; //!< Time in seconds occupied by extrusion
double unretracted_travel_time; //!< Time in seconds occupied by non-retracted travel (non-extrusion)
double retracted_travel_time; //!< Time in seconds occupied by retracted travel (non-extrusion)
double material; //!< Material used (in mm^3)
public:
/*!
* Basic contructor
*
* \param extrude_time Time in seconds occupied by extrusion
* \param unretracted_travel_time Time in seconds occupied by non-retracted travel (non-extrusion)
* \param retracted_travel_time Time in seconds occupied by retracted travel (non-extrusion)
* \param material Material used (in mm^3)
*/
TimeMaterialEstimates(double extrude_time, double unretracted_travel_time, double retracted_travel_time, double material)
: extrude_time(extrude_time)
, unretracted_travel_time(unretracted_travel_time)
, retracted_travel_time(retracted_travel_time)
, material(material)
{
}
/*!
* Basic constructor initializing all estimates to zero.
*/
TimeMaterialEstimates()
: extrude_time(0.0)
, unretracted_travel_time(0.0)
, retracted_travel_time(0.0)
, material(0.0)
{
}
/*!
* Set all estimates to zero.
*/
void reset()
{
extrude_time = 0.0;
unretracted_travel_time = 0.0;
retracted_travel_time = 0.0;
material = 0.0;
}
/*!
* Pointwise addition of estimate stats
*
* \param other The estimates to add to these estimates.
* \return The resulting estimates
*/
TimeMaterialEstimates operator+(const TimeMaterialEstimates& other)
{
return TimeMaterialEstimates(extrude_time+other.extrude_time, unretracted_travel_time+other.unretracted_travel_time, retracted_travel_time+other.retracted_travel_time, material+other.material);
}
/*!
* In place pointwise addition of estimate stats
*
* \param other The estimates to add to these estimates.
* \return These estimates
*/
TimeMaterialEstimates& operator+=(const TimeMaterialEstimates& other)
{
extrude_time += other.extrude_time;
unretracted_travel_time += other.unretracted_travel_time;
retracted_travel_time += other.retracted_travel_time;
material += other.material;
return *this;
}
/*!
* \brief Subtracts the specified estimates from these estimates and returns
* the result.
*
* Each of the estimates in this class are individually subtracted.
*
* \param other The estimates to subtract from these estimates.
* \return These estimates with the specified estimates subtracted.
*/
TimeMaterialEstimates operator-(const TimeMaterialEstimates& other);
/*!
* \brief Subtracts the specified elements from these estimates.
*
* This causes the estimates in this instance to change. Each of the
* estimates in this class are individually subtracted.
*
* \param other The estimates to subtract from these estimates.
* \return A reference to this instance.
*/
TimeMaterialEstimates& operator-=(const TimeMaterialEstimates& other);
/*!
* Get total time estimate. The different time estimate member values added together.
*
* \return the total of all different time estimate values
*/
double getTotalTime() const
{
return extrude_time + unretracted_travel_time + retracted_travel_time;
}
/*!
* Get the total time during which the head is not retracted.
*
* This includes extrusion time and non-retracted travel time
*
* \return the total time during which the head is not retracted.
*/
double getTotalUnretractedTime() const
{
return extrude_time + unretracted_travel_time;
}
/*!
* Get the total travel time.
*
* This includes the retracted travel time as well as the unretracted travel time.
*
* \return the total travel time.
*/
double getTravelTime() const
{
return retracted_travel_time + unretracted_travel_time;
}
/*!
* Get the extrusion time.
*
* \return extrusion time.
*/
double getExtrudeTime() const
{
return extrude_time;
}
/*!
* Get the amount of material used in mm^3.
*
* \return amount of material
*/
double getMaterial() const
{
return material;
}
};
/*!
* A class for representing a planned path.
*
* A path consists of several segments of the same type of movement: retracted travel, infill extrusion, etc.
*
* This is a compact premature representation in which are line segments have the same config, i.e. the config of this path.
*
* In the final representation (gcode) each line segment may have different properties,
* which are added when the generated GCodePaths are processed.
*/
class GCodePath
{
public:
GCodePathConfig* config; //!< The configuration settings of the path.
SpaceFillType space_fill_type; //!< The type of space filling of which this path is a part
float flow; //!< A type-independent flow configuration (used for wall overlap compensation)
bool retract; //!< Whether the path is a move path preceded by a retraction move; whether the path is a retracted move path.
bool perform_z_hop; //!< Whether to perform a z_hop in this path, which is assumed to be a travel path.
std::vector<Point> points; //!< The points constituting this path.
bool done;//!< Path is finished, no more moves should be added, and a new path should be started instead of any appending done to this one.
bool spiralize; //!< Whether to gradually increment the z position during the printing of this path. A sequence of spiralized paths should start at the given layer height and end in one layer higher.
TimeMaterialEstimates estimates; //!< Naive time and material estimates
/*!
* Whether this config is the config of a travel path.
*
* \return Whether this config is the config of a travel path.
*/
bool isTravelPath()
{
return config->isTravelPath();
}
/*!
* Get the material flow in mm^3 per mm traversed.
*
* \warning Can only be called after the layer height has been set (which is done while writing the gcode!)
*
* \return The flow
*/
double getExtrusionMM3perMM()
{
return flow * config->getExtrusionMM3perMM();
}
/*!
* Get the actual line width (modulated by the flow)
* \return the actual line width as shown in layer view
*/
int getLineWidth()
{
return flow * config->getLineWidth() * config->getFlowPercentage() / 100.0;
}
};
class GCodePlanner; // forward declaration so that ExtruderPlan can be a friend
class LayerPlanBuffer; // forward declaration so that ExtruderPlan can be a friend
/*!
* An extruder plan contains all planned paths (GCodePath) pertaining to a single extruder train.
*
* It allows for temperature command inserts which can be inserted in between paths.
*/
class ExtruderPlan
{
friend class GCodePlanner; // TODO: GCodePlanner still does a lot which should actually be handled in this class.
friend class LayerPlanBuffer; // TODO: LayerPlanBuffer handles paths directly
protected:
std::vector<GCodePath> paths; //!< The paths planned for this extruder
std::list<NozzleTempInsert> inserts; //!< The nozzle temperature command inserts, to be inserted in between paths
int extruder; //!< The extruder used for this paths in the current plan.
double heated_pre_travel_time; //!< The time at the start of this ExtruderPlan during which the head travels and has a temperature of initial_print_temperature
double initial_printing_temperature; //!< The required temperature at the start of this extruder plan.
double printing_temperature; //!< The normal temperature for printing this extruder plan. That start and end of this extruder plan may deviate because of the initial and final print temp
std::optional<std::list<NozzleTempInsert>::iterator> printing_temperature_command; //!< The command to heat from the printing temperature of this extruder plan to the printing temperature of the next extruder plan (if it has the same extruder).
std::optional<double> prev_extruder_standby_temp; //!< The temperature to which to set the previous extruder. Not used if the previous extruder plan was the same extruder.
TimeMaterialEstimates estimates; //!< Accumulated time and material estimates for all planned paths within this extruder plan.
public:
/*!
* Simple contructor.
*
* \warning Doesn't set the required temperature yet.
*
* \param extruder The extruder number for which this object is a plan.
* \param start_position The position the head is when this extruder plan starts
*/
ExtruderPlan(int extruder, Point start_position, int layer_nr, bool is_initial_layer, int layer_thickness, FanSpeedLayerTimeSettings& fan_speed_layer_time_settings, const RetractionConfig& retraction_config);
/*!
* Add a new Insert, constructed with the given arguments
*
* \see NozzleTempInsert
*
* \param contructor_args The arguments for the constructor of an insert
*/
template<typename... Args>
void insertCommand(Args&&... contructor_args)
{
inserts.emplace_back(contructor_args...);
}
/*!
* Insert the inserts into gcode which should be inserted before \p path_idx
*
* \param path_idx The index into ExtruderPlan::paths which is currently being consider for temperature command insertion
* \param gcode The gcode exporter to which to write the temperature command.
*/
void handleInserts(unsigned int& path_idx, GCodeExport& gcode)
{
while ( ! inserts.empty() && path_idx >= inserts.front().path_idx)
{ // handle the Insert to be inserted before this path_idx (and all inserts not handled yet)
inserts.front().write(gcode);
inserts.pop_front();
}
}
/*!
* Insert all remaining temp inserts into gcode, to be called at the end of an extruder plan
*
* Inserts temperature commands which should be inserted _after_ the last path.
* Also inserts all temperatures which should have been inserted earlier,
* but for which ExtruderPlan::handleInserts hasn't been called correctly.
*
* \param gcode The gcode exporter to which to write the temperature command.
*/
void handleAllRemainingInserts(GCodeExport& gcode)
{
while ( ! inserts.empty() )
{ // handle the Insert to be inserted before this path_idx (and all inserts not handled yet)
NozzleTempInsert& insert = inserts.front();
assert(insert.path_idx == paths.size());
insert.write(gcode);
inserts.pop_front();
}
}
/*!
* Applying speed corrections for minimal layer times and determine the fanSpeed.
*
* \param force_minimal_layer_time Whether we should apply speed changes and perhaps a head lift in order to meet the minimal layer time
*/
void processFanSpeedAndMinimalLayerTime(bool force_minimal_layer_time);
/*!
* Set the extrude speed factor. This is used for printing slower than normal.
*
* Leaves the extrusion speed as is for values of 1.0
*
* \param speedFactor The factor by which to alter the extrusion move speed
*/
void setExtrudeSpeedFactor(double speedFactor);
/*!
* Get the extrude speed factor. This is used for printing slower than normal.
*
* \return The factor by which to alter the extrusion move speed
*/
double getExtrudeSpeedFactor();
/*!
* Set the travel speed factor. This is used for performing non-extrusion travel moves slower than normal.
*
* Leaves the extrusion speed as is for values of 1.0
*
* \param speedFactor The factor by which to alter the non-extrusion move speed
*/
void setTravelSpeedFactor(double speedFactor);
/*!
* Get the travel speed factor. This is used for travelling slower than normal.
*
* Limited to at most 1.0
*
* \return The factor by which to alter the non-extrusion move speed
*/
double getTravelSpeedFactor();
/*!
* Get the fan speed computed for this extruder plan
*
* \warning assumes ExtruderPlan::processFanSpeedAndMinimalLayerTime has already been called
*
* \return The fan speed computed in processFanSpeedAndMinimalLayerTime
*/
double getFanSpeed();
protected:
Point start_position; //!< The position the print head was at at the start of this extruder plan
int layer_nr; //!< The layer number at which we are currently printing.
bool is_initial_layer; //!< Whether this extruder plan is printed on the very first layer (which might be raft)
int layer_thickness; //!< The thickness of this layer in Z-direction
FanSpeedLayerTimeSettings& fan_speed_layer_time_settings; //!< The fan speed and layer time settings used to limit this extruder plan
const RetractionConfig& retraction_config; //!< The retraction settings for the extruder of this plan
double extrudeSpeedFactor; //!< The factor by which to alter the extrusion move speed
double travelSpeedFactor; //!< The factor by which to alter the non-extrusion move speed
double extraTime; //!< Extra waiting time at the and of this extruder plan, so that the filament can cool
double totalPrintTime; //!< The total naive time estimate for this extruder plan
double fan_speed; //!< The fan speed to be used during this extruder plan
/*!
* Set the fan speed to be used while printing this extruder plan
*
* \param fan_speed The speed for the fan
*/
void setFanSpeed(double fan_speed);
/*!
* Force the minimal layer time to hold by slowing down and lifting the head if required.
*
*/
void forceMinimalLayerTime(double minTime, double minimalSpeed, double travelTime, double extrusionTime);
/*!
* Compute naive time estimates (without accounting for slow down at corners etc.) and naive material estimates (without accounting for MergeInfillLines)
* and store them in each ExtruderPlan and each GCodePath.
*
* \return the total estimates of this layer
*/
TimeMaterialEstimates computeNaiveTimeEstimates();
};
class LayerPlanBuffer; // forward declaration to prevent circular dependency
/*!
* The GCodePlanner class stores multiple moves that are planned.
*
*
* It facilitates the combing to keep the head inside the print.
* It also keeps track of the print time estimate for this planning so speed adjustments can be made for the minimal-layer-time.
*
* A GCodePlanner is also knows as a 'layer plan'.
*
*/
class GCodePlanner : public NoCopy
{
friend class LayerPlanBuffer;
friend class GCodePlannerTest;
private:
SliceDataStorage& storage; //!< The polygon data obtained from FffPolygonProcessor
int layer_nr; //!< The layer number of this layer plan
int is_initial_layer; //!< Whether this is the first layer (which might be raft)
int z;
int layer_thickness;
Point start_position;
Point lastPosition;
std::vector<ExtruderPlan> extruder_plans; //!< should always contain at least one ExtruderPlan
int last_extruder_previous_layer; //!< The last id of the extruder with which was printed in the previous layer
SettingsBaseVirtual* last_planned_extruder_setting_base; //!< The setting base of the last planned extruder.
SliceLayerPart* was_inside; //!< The layer part the last planned (extrusion) move was inside (if any)
SliceLayerPart* is_inside; //!< The layer part the destination of the next planned travel move is inside (if any)
Polygons comb_boundary_inside; //!< The boundary within which to comb, or to move into when performing a retraction.
Comb* comb;
std::vector<FanSpeedLayerTimeSettings>& fan_speed_layer_time_settings_per_extruder;
private:
/*!
* Either create a new path with the given config or return the last path if it already had that config.
* If GCodePlanner::forceNewPathStart has been called a new path will always be returned.
*
* \param config The config used for the path returned
* \param space_fill_type The type of space filling which this path employs
* \param flow (optional) A ratio for the extrusion speed
* \param spiralize Whether to gradually increase the z while printing. (Note that this path may be part of a sequence of spiralized paths, forming one polygon)
* \return A path with the given config which is now the last path in GCodePlanner::paths
*/
GCodePath* getLatestPathWithConfig(GCodePathConfig* config, SpaceFillType space_fill_type, float flow = 1.0, bool spiralize = false);
public:
/*!
* Force GCodePlanner::getLatestPathWithConfig to return a new path.
*
* This function is introduced because in some cases
* GCodePlanner::getLatestPathWithConfig is called consecutively with the same config pointer,
* though the content of the config has changed.
*
* Example cases:
* - when changing extruder, the same travel config is used, but its extruder field is changed.
*/
void forceNewPathStart();
/*!
*
* \param fan_speed_layer_time_settings_per_extruder The fan speed and layer time settings for each extruder.
* \param travel_avoid_other_parts Whether to avoid other layer parts when travaeling through air.
* \param travel_avoid_distance The distance by which to avoid other layer parts when traveling through air.
* \param last_position The position of the head at the start of this gcode layer
* \param combing_mode Whether combing is enabled and full or within infill only.
*/
GCodePlanner(SliceDataStorage& storage, int layer_nr, int z, int layer_height, Point last_position, int current_extruder, std::vector<FanSpeedLayerTimeSettings>& fan_speed_layer_time_settings_per_extruder, CombingMode combing_mode, int64_t comb_boundary_offset, bool travel_avoid_other_parts, int64_t travel_avoid_distance);
~GCodePlanner();
void overrideFanSpeeds(double speed);
/*!
* Get the settings base of the last extruder planned.
* \return the settings base of the last extruder planned.
*/
SettingsBaseVirtual* getLastPlannedExtruderTrainSettings();
private:
/*!
* Compute the boundary within which to comb, or to move into when performing a retraction.
* \param combing_mode Whether combing is enabled and full or within infill only.
* \return the comb_boundary_inside
*/
Polygons computeCombBoundaryInside(CombingMode combing_mode);
public:
int getLayerNr()
{
return layer_nr;
}
Point getLastPosition()
{
return lastPosition;
}
/*!
* return whether the last position planned was inside the mesh (used in combing)
*/
bool getIsInsideMesh()
{
return was_inside;
}
/*!
* send a line segment through the command socket from the previous point to the given point \p to
*/
void sendLineTo(PrintFeatureType print_feature_type, Point to, int line_width)
{
CommandSocket::sendLineTo(print_feature_type, to, line_width);
}
/*!
* Set whether the next destination is inside a layer part or not.
*
* Features like infill, walls, skin etc. are considered inside.
* Features like prime tower and support are considered outside.
* \param inside_part The part in which the newly planned position is inside, or nullptr if not inside anything
*/
void setIsInside(SliceLayerPart* inside_part);
bool setExtruder(int extruder);
/*!
* Get the last planned extruder.
*/
int getExtruder()
{
return extruder_plans.back().extruder;
}
/*!
* Add a travel path to a certain point, retract if needed and when avoiding boundary crossings:
* avoiding obstacles and comb along the boundary of parts.
*
* \param p The point to travel to
*/
GCodePath& addTravel(Point p);
/*!
* Add a travel path to a certain point and retract if needed.
*
* No combing is performed.
*
* \param p The point to travel to
* \param path (optional) The travel path to which to add the point \p p
*/
GCodePath& addTravel_simple(Point p, GCodePath* path = nullptr);
/*!
* Add an extrusion move to a certain point, optionally with a different flow than the one in the \p config.
*
* \param p The point to extrude to
* \param config The config with which to extrude
* \param space_fill_type Of what space filling type this extrusion move is a part
* \param flow A modifier of the extrusion width which would follow from the \p config
* \param spiralize Whether to gradually increase the z while printing. (Note that this path may be part of a sequence of spiralized paths, forming one polygon)
*/
void addExtrusionMove(Point p, GCodePathConfig* config, SpaceFillType space_fill_type, float flow = 1.0, bool spiralize = false);
/*!
* Add polygon to the gcode starting at vertex \p startIdx
* \param polygon The polygon
* \param startIdx The index of the starting vertex of the \p polygon
* \param config The config with which to print the polygon lines
* \param wall_overlap_computation The wall overlap compensation calculator for each given segment (optionally nullptr)
* \param wall_0_wipe_dist The distance to travel along the polygon after it has been laid down, in order to wipe the start and end of the wall together
* \param spiralize Whether to gradually increase the z height from the normal layer height to the height of the next layer over this polygon
*/
void addPolygon(PolygonRef polygon, int startIdx, GCodePathConfig* config, WallOverlapComputation* wall_overlap_computation = nullptr, coord_t wall_0_wipe_dist = 0, bool spiralize = false);
/*!
* Add polygons to the gcode with optimized order.
*
* When \p spiralize is true, each polygon will gradually increase from a z corresponding to this layer to the z corresponding to the next layer.
* Doing this for each polygon means there is a chance for the print head to crash into already printed parts,
* but doing it for the last polygon only would mean you are printing half of the layer in non-spiralize mode,
* while each layer starts with a different part.
* Two towers would result in alternating spiralize and non-spiralize layers.
*
* \param polygons The polygons
* \param config The config with which to print the polygon lines
* \param wall_overlap_computation The wall overlap compensation calculator for each given segment (optionally nullptr)
* \param z_seam_type The seam type / poly start optimizer
* \param wall_0_wipe_dist The distance to travel along each polygon after it has been laid down, in order to wipe the start and end of the wall together
* \param spiralize Whether to gradually increase the z height from the normal layer height to the height of the next layer over each polygon printed
*/
void addPolygonsByOptimizer(Polygons& polygons, GCodePathConfig* config, WallOverlapComputation* wall_overlap_computation = nullptr, EZSeamType z_seam_type = EZSeamType::SHORTEST, coord_t wall_0_wipe_dist = 0, bool spiralize = false);
/*!
* Add lines to the gcode with optimized order.
* \param polygons The lines
* \param config The config of the lines
* \param space_fill_type The type of space filling used to generate the line segments (should be either Lines or PolyLines!)
* \param wipe_dist (optional) the distance wiped without extruding after laying down a line.
*/
void addLinesByOptimizer(Polygons& polygons, GCodePathConfig* config, SpaceFillType space_fill_type, int wipe_dist = 0);
/*!
* Compute naive time estimates (without accounting for slow down at corners etc.) and naive material estimates (without accounting for MergeInfillLines)
* and store them in each ExtruderPlan and each GCodePath.
*
* \warning This function recomputes values which are already computed if you've called processFanSpeedAndMinimalLayerTime
*
* \return the total estimates of this layer
*/
TimeMaterialEstimates computeNaiveTimeEstimates();
/*!
* Write the planned paths to gcode
*
* \param gcode The gcode to write the planned paths to
*/
void writeGCode(GCodeExport& gcode);
/*!
* Complete all GcodePathConfigs by
* - altering speeds to conform to speed_print_layer_0 and
* speed_travel_layer_0
* - setting the layer_height (and thereby computing the extrusionMM3perMM)
*/
void completeConfigs();
/*!
* Interpolate between the initial layer speeds and the eventual speeds.
*/
void processInitialLayersSpeedup();
/*!
* Whether the current retracted path is to be an extruder switch retraction.
* This function is used to avoid a G10 S1 after a G10.
*
* \param gcode The gcode to write the planned paths to
* \param extruder_plan_idx The index of the current extruder plan
* \param path_idx The index of the current retracted path
* \return Whether the path should be an extgruder switch retracted path
*/
bool makeRetractSwitchRetract(GCodeExport& gcode, unsigned int extruder_plan_idx, unsigned int path_idx);
/*!
* Writes a path to GCode and performs coasting, or returns false if it did nothing.
*
* Coasting replaces the last piece of an extruded path by move commands and uses the oozed material to lay down lines.
*
* \param gcode The gcode to write the planned paths to
* \param extruder_plan_idx The index of the current extruder plan
* \param path_idx The index into GCodePlanner::paths for the next path to be written to GCode.
* \param layerThickness The height of the current layer.
* \param coasting_volume The volume otherwise leaked during a normal move.
* \param coasting_speed The speed at which to move during move-coasting.
* \param coasting_min_volume The minimal volume a path should have (before starting to coast) which builds up enough pressure to ooze as much as \p coasting_volume.
* \return Whether any GCode has been written for the path.
*/
bool writePathWithCoasting(GCodeExport& gcode, unsigned int extruder_plan_idx, unsigned int path_idx, int64_t layerThickness, double coasting_volume, double coasting_speed, double coasting_min_volume);
/*!
* Applying speed corrections for minimal layer times and determine the fanSpeed.
*/
void processFanSpeedAndMinimalLayerTime();
/*!
* Add a travel move to the layer plan to move inside the current layer part by a given distance away from the outline.
* This is supposed to be called when the nozzle is around the boundary of a layer part, not when the nozzle is in the middle of support, or in the middle of the air.
*
* \param distance The distance to the comb boundary after we moved inside it.
* \param part_outline The part in which we last resided
*/
void moveInsideCombBoundary(int distance, const SliceLayerPart& part);
};
}//namespace cura
#endif//GCODE_PLANNER_H
+322 -75
Ver Arquivo
@@ -1,107 +1,354 @@
/** Copyright (C) 2013 David Braam - Released under terms of the AGPLv3 License */
#include "infill.h"
#include "functional"
#include "utils/polygonUtils.h"
#include "utils/logoutput.h"
namespace cura {
void generateConcentricInfill(Polygons outline, Polygons& result, int inset_value)
int Infill::computeScanSegmentIdx(int x, int line_width)
{
while(outline.size() > 0)
if (x < 0)
{
for (unsigned int polyNr = 0; polyNr < outline.size(); polyNr++)
{
PolygonRef r = outline[polyNr];
result.add(r);
}
outline = outline.offset(-inset_value);
return (x + 1) / line_width - 1;
// - 1 because -1 belongs to scansegment -1
// + 1 because -line_width belongs to scansegment -1
}
return x / line_width;
}
void Infill::generate(Polygons& result_polygons, Polygons& result_lines)
{
if (in_outline.size() == 0) return;
if (line_distance == 0) return;
Polygons outline_offsetted;
switch(pattern)
{
case EFillMethod::GRID:
generateGridInfill(result_lines);
break;
case EFillMethod::LINES:
generateLineInfill(result_lines, line_distance, fill_angle, 0);
break;
case EFillMethod::CUBIC:
generateCubicInfill(result_lines);
break;
case EFillMethod::TETRAHEDRAL:
generateTetrahedralInfill(result_lines);
break;
case EFillMethod::TRIANGLES:
generateTriangleInfill(result_lines);
break;
case EFillMethod::CONCENTRIC:
generateConcentricInfill(result_polygons, line_distance);
break;
case EFillMethod::CONCENTRIC_3D:
generateConcentric3DInfill(result_polygons);
break;
case EFillMethod::ZIG_ZAG:
generateZigZagInfill(result_lines, line_distance, fill_angle, connected_zigzags, use_endpieces);
break;
default:
logError("Fill pattern has unknown value.\n");
break;
}
}
void generateAutomaticInfill(const Polygons& in_outline, Polygons& result,
int extrusionWidth, int lineSpacing,
int infillOverlap, double rotation)
void Infill::generateConcentricInfill(Polygons& result, int inset_value)
{
if (lineSpacing > extrusionWidth * 4)
Polygons first_concentric_wall = in_outline.offset(outline_offset - line_distance + infill_line_width / 2); // - infill_line_width / 2 cause generateConcentricInfill expects [outline] to be the outer most polygon instead of the outer outline
result.add(first_concentric_wall);
if (perimeter_gaps)
{
generateGridInfill(in_outline, result, extrusionWidth, lineSpacing,
infillOverlap, rotation);
const Polygons inner = first_concentric_wall.offset(infill_line_width / 2 + perimeter_gaps_extra_offset);
const Polygons gaps_here = in_outline.difference(inner);
perimeter_gaps->add(gaps_here);
}
generateConcentricInfill(first_concentric_wall, result, inset_value);
}
void Infill::generateConcentricInfill(Polygons& first_concentric_wall, Polygons& result, int inset_value)
{
Polygons* prev_inset = &first_concentric_wall;
Polygons next_inset;
while (prev_inset->size() > 0)
{
next_inset = prev_inset->offset(-inset_value);
result.add(next_inset);
if (perimeter_gaps)
{
const Polygons outer = prev_inset->offset(-infill_line_width / 2 - perimeter_gaps_extra_offset);
const Polygons inner = next_inset.offset(infill_line_width / 2 + perimeter_gaps_extra_offset);
const Polygons gaps_here = outer.difference(inner);
perimeter_gaps->add(gaps_here);
}
prev_inset = &next_inset;
}
}
void Infill::generateConcentric3DInfill(Polygons& result)
{
int period = line_distance * 2;
int shift = int64_t(one_over_sqrt_2 * z) % period;
shift = std::min(shift, period - shift); // symmetry due to the fact that we are applying the shift in both directions
shift = std::min(shift, period / 2 - infill_line_width / 2); // don't put lines too close to each other
shift = std::max(shift, infill_line_width / 2); // don't put lines too close to each other
Polygons first_wall;
// in contrast to concentric infill we dont do "- infill_line_width / 2" cause this is already handled by the max two lines above
first_wall = in_outline.offset(outline_offset - shift);
generateConcentricInfill(first_wall, result, period);
first_wall = in_outline.offset(outline_offset - period + shift);
generateConcentricInfill(first_wall, result, period);
}
void Infill::generateGridInfill(Polygons& result)
{
generateLineInfill(result, line_distance, fill_angle, 0);
generateLineInfill(result, line_distance, fill_angle + 90, 0);
}
void Infill::generateCubicInfill(Polygons& result)
{
int64_t shift = one_over_sqrt_2 * z;
generateLineInfill(result, line_distance, fill_angle, shift);
generateLineInfill(result, line_distance, fill_angle + 120, shift);
generateLineInfill(result, line_distance, fill_angle + 240, shift);
}
void Infill::generateTetrahedralInfill(Polygons& result)
{
int period = line_distance * 2;
int shift = int64_t(one_over_sqrt_2 * z) % period;
shift = std::min(shift, period - shift); // symmetry due to the fact that we are applying the shift in both directions
shift = std::min(shift, period / 2 - infill_line_width / 2); // don't put lines too close to each other
shift = std::max(shift, infill_line_width / 2); // don't put lines too close to each other
generateLineInfill(result, period, fill_angle, shift);
generateLineInfill(result, period, fill_angle, -shift);
generateLineInfill(result, period, fill_angle + 90, shift);
generateLineInfill(result, period, fill_angle + 90, -shift);
}
void Infill::generateTriangleInfill(Polygons& result)
{
generateLineInfill(result, line_distance, fill_angle, 0);
generateLineInfill(result, line_distance, fill_angle + 60, 0);
generateLineInfill(result, line_distance, fill_angle + 120, 0);
}
void Infill::addLineInfill(Polygons& result, const PointMatrix& rotation_matrix, const int scanline_min_idx, const int line_distance, const AABB boundary, std::vector<std::vector<int64_t>>& cut_list, int64_t shift)
{
auto addLine = [&](Point from, Point to)
{
PolygonRef p = result.newPoly();
p.add(rotation_matrix.unapply(from));
p.add(rotation_matrix.unapply(to));
};
auto compare_int64_t = [](const void* a, const void* b)
{
int64_t n = (*(int64_t*)a) - (*(int64_t*)b);
if (n < 0)
{
return -1;
}
if (n > 0)
{
return 1;
}
return 0;
};
int scanline_idx = 0;
for(int64_t x = scanline_min_idx * line_distance + shift; x < boundary.max.X; x += line_distance)
{
std::vector<int64_t>& crossings = cut_list[scanline_idx];
qsort(crossings.data(), crossings.size(), sizeof(int64_t), compare_int64_t);
for(unsigned int crossing_idx = 0; crossing_idx + 1 < crossings.size(); crossing_idx += 2)
{
if (crossings[crossing_idx + 1] - crossings[crossing_idx] < infill_line_width / 5)
{ // segment is too short to create infill
continue;
}
addLine(Point(x, crossings[crossing_idx]), Point(x, crossings[crossing_idx + 1]));
}
scanline_idx += 1;
}
}
void Infill::generateLineInfill(Polygons& result, int line_distance, const double& fill_angle, int64_t shift)
{
PointMatrix rotation_matrix(fill_angle);
NoZigZagConnectorProcessor lines_processor(rotation_matrix, result);
bool connected_zigzags = false;
generateLinearBasedInfill(outline_offset, result, line_distance, rotation_matrix, lines_processor, connected_zigzags, shift);
}
void Infill::generateZigZagInfill(Polygons& result, const int line_distance, const double& fill_angle, const bool connected_zigzags, const bool use_endpieces)
{
PointMatrix rotation_matrix(fill_angle);
if (use_endpieces)
{
if (connected_zigzags)
{
ZigzagConnectorProcessorConnectedEndPieces zigzag_processor(rotation_matrix, result);
generateLinearBasedInfill(outline_offset - infill_line_width / 2, result, line_distance, rotation_matrix, zigzag_processor, connected_zigzags, 0);
}
else
{
ZigzagConnectorProcessorDisconnectedEndPieces zigzag_processor(rotation_matrix, result);
generateLinearBasedInfill(outline_offset - infill_line_width / 2, result, line_distance, rotation_matrix, zigzag_processor, connected_zigzags, 0);
}
}
else
{
ZigzagConnectorProcessorNoEndPieces zigzag_processor(rotation_matrix, result);
generateLinearBasedInfill(outline_offset - infill_line_width / 2, result, line_distance, rotation_matrix, zigzag_processor, connected_zigzags, 0);
}
}
/*
* algorithm:
* 1. for each line segment of each polygon:
* store the intersections of that line segment with all scanlines in a mapping (vector of vectors) from scanline to intersections
* (zigzag): add boundary segments to result
* 2. for each scanline:
* sort the associated intersections
* and connect them using the even-odd rule
*
* rough explanation of the zigzag algorithm:
* while walking around (each) polygon (1.)
* if polygon intersects with even scanline
* start boundary segment (add each following segment to the [result])
* when polygon intersects with a scanline again
* stop boundary segment (stop adding segments to the [result])
* (see infill/ZigzagConnectorProcessor.h for actual implementation details)
*
*
* we call the areas between two consecutive scanlines a 'scansegment'.
* Scansegment x is the area between scanline x and scanline x+1
* Edit: the term scansegment is wrong, since I call a boundary segment leaving from an even scanline to the left as belonging to an even scansegment,
* while I also call a boundary segment leaving from an even scanline toward the right as belonging to an even scansegment.
*/
void Infill::generateLinearBasedInfill(const int outline_offset, Polygons& result, const int line_distance, const PointMatrix& rotation_matrix, ZigzagConnectorProcessor& zigzag_connector_processor, const bool connected_zigzags, int64_t extra_shift)
{
if (line_distance == 0)
{
return;
}
if (in_outline.size() == 0)
{
return;
}
int shift = extra_shift + this->shift;
Polygons outline;
if (outline_offset != 0)
{
outline = in_outline.offset(outline_offset);
if (perimeter_gaps)
{
perimeter_gaps->add(in_outline.difference(outline.offset(infill_line_width / 2 + perimeter_gaps_extra_offset)));
}
}
else
{
generateLineInfill(in_outline, result, extrusionWidth, lineSpacing,
infillOverlap, rotation);
outline = in_outline;
}
}
void generateGridInfill(const Polygons& in_outline, Polygons& result,
int extrusionWidth, int lineSpacing, int infillOverlap,
double rotation)
{
generateLineInfill(in_outline, result, extrusionWidth, lineSpacing * 2,
infillOverlap, rotation);
generateLineInfill(in_outline, result, extrusionWidth, lineSpacing * 2,
infillOverlap, rotation + 90);
}
outline = outline.offset(infill_overlap);
int compare_int64_t(const void* a, const void* b)
{
int64_t n = (*(int64_t*)a) - (*(int64_t*)b);
if (n < 0) return -1;
if (n > 0) return 1;
return 0;
}
if (outline.size() == 0)
{
return;
}
outline.applyMatrix(rotation_matrix);
if (shift < 0)
{
shift = line_distance - (-shift) % line_distance;
}
else
{
shift = shift % line_distance;
}
void generateLineInfill(const Polygons& in_outline, Polygons& result, int extrusionWidth, int lineSpacing, int infillOverlap, double rotation)
{
Polygons outline = in_outline.offset(extrusionWidth * infillOverlap / 100);
PointMatrix matrix(rotation);
outline.applyMatrix(matrix);
AABB boundary(outline);
boundary.min.X = ((boundary.min.X / lineSpacing) - 1) * lineSpacing;
int lineCount = (boundary.max.X - boundary.min.X + (lineSpacing - 1)) / lineSpacing;
vector<vector<int64_t> > cutList;
for(int n=0; n<lineCount; n++)
cutList.push_back(vector<int64_t>());
for(unsigned int polyNr=0; polyNr < outline.size(); polyNr++)
int scanline_min_idx = computeScanSegmentIdx(boundary.min.X - shift, line_distance);
int line_count = computeScanSegmentIdx(boundary.max.X - shift, line_distance) + 1 - scanline_min_idx;
std::vector<std::vector<int64_t> > cut_list; // mapping from scanline to all intersections with polygon segments
for(int scanline_idx = 0; scanline_idx < line_count; scanline_idx++)
{
Point p1 = outline[polyNr][outline[polyNr].size()-1];
for(unsigned int i=0; i < outline[polyNr].size(); i++)
cut_list.push_back(std::vector<int64_t>());
}
for(unsigned int poly_idx = 0; poly_idx < outline.size(); poly_idx++)
{
PolygonRef poly = outline[poly_idx];
Point p0 = poly.back();
zigzag_connector_processor.registerVertex(p0); // always adds the first point to ZigzagConnectorProcessorEndPieces::first_zigzag_connector when using a zigzag infill type
for(unsigned int point_idx = 0; point_idx < poly.size(); point_idx++)
{
Point p0 = outline[polyNr][i];
int idx0 = (p0.X - boundary.min.X) / lineSpacing;
int idx1 = (p1.X - boundary.min.X) / lineSpacing;
int64_t xMin = p0.X, xMax = p1.X;
if (p0.X > p1.X) { xMin = p1.X; xMax = p0.X; }
if (idx0 > idx1) { int tmp = idx0; idx0 = idx1; idx1 = tmp; }
for(int idx = idx0; idx<=idx1; idx++)
Point p1 = poly[point_idx];
if (p1.X == p0.X)
{
int x = (idx * lineSpacing) + boundary.min.X + lineSpacing / 2;
if (x < xMin) continue;
if (x >= xMax) continue;
int y = p0.Y + (p1.Y - p0.Y) * (x - p0.X) / (p1.X - p0.X);
cutList[idx].push_back(y);
zigzag_connector_processor.registerVertex(p1);
// TODO: how to make sure it always adds the shortest line? (in order to prevent overlap with the zigzag connectors)
// note: this is already a problem for normal infill, but hasn't really cothered anyone so far.
p0 = p1;
continue;
}
p1 = p0;
int scanline_idx0;
int scanline_idx1;
// this way of handling the indices takes care of the case where a boundary line segment ends exactly on a scanline:
// in case the next segment moves back from that scanline either 2 or 0 scanline-boundary intersections are created
// otherwise only 1 will be created, counting as an actual intersection
int direction = 1;
if (p0.X < p1.X)
{
scanline_idx0 = computeScanSegmentIdx(p0.X - shift, line_distance) + 1; // + 1 cause we don't cross the scanline of the first scan segment
scanline_idx1 = computeScanSegmentIdx(p1.X - shift, line_distance); // -1 cause the vertex point is handled in the next segment (or not in the case which looks like >)
}
else
{
direction = -1;
scanline_idx0 = computeScanSegmentIdx(p0.X - shift, line_distance); // -1 cause the vertex point is handled in the previous segment (or not in the case which looks like >)
scanline_idx1 = computeScanSegmentIdx(p1.X - shift, line_distance) + 1; // + 1 cause we don't cross the scanline of the first scan segment
}
for(int scanline_idx = scanline_idx0; scanline_idx != scanline_idx1 + direction; scanline_idx += direction)
{
int x = scanline_idx * line_distance + shift;
int y = p1.Y + (p0.Y - p1.Y) * (x - p1.X) / (p0.X - p1.X);
assert(scanline_idx - scanline_min_idx >= 0 && scanline_idx - scanline_min_idx < int(cut_list.size()) && "reading infill cutlist index out of bounds!");
cut_list[scanline_idx - scanline_min_idx].push_back(y);
Point scanline_linesegment_intersection(x, y);
zigzag_connector_processor.registerScanlineSegmentIntersection(scanline_linesegment_intersection, scanline_idx % 2 == 0);
}
zigzag_connector_processor.registerVertex(p1);
p0 = p1;
}
zigzag_connector_processor.registerPolyFinished();
}
int idx = 0;
for(int64_t x = boundary.min.X + lineSpacing / 2; x < boundary.max.X; x += lineSpacing)
if (cut_list.size() == 0)
{
qsort(cutList[idx].data(), cutList[idx].size(), sizeof(int64_t), compare_int64_t);
for(unsigned int i = 0; i + 1 < cutList[idx].size(); i+=2)
{
if (cutList[idx][i+1] - cutList[idx][i] < extrusionWidth / 5)
continue;
PolygonRef p = result.newPoly();
p.add(matrix.unapply(Point(x, cutList[idx][i])));
p.add(matrix.unapply(Point(x, cutList[idx][i+1])));
}
idx += 1;
return;
}
if (connected_zigzags && cut_list.size() == 1 && cut_list[0].size() <= 2)
{
return; // don't add connection if boundary already contains whole outline!
}
addLineInfill(result, rotation_matrix, scanline_min_idx, line_distance, boundary, cut_list, shift);
}
}//namespace cura
+230 -5
Ver Arquivo
@@ -3,13 +3,238 @@
#define INFILL_H
#include "utils/polygon.h"
#include "settings/settings.h"
// #include "ZigzagConnectorProcessor.h"
#include "infill/ZigzagConnectorProcessor.h"
#include "infill/NoZigZagConnectorProcessor.h"
#include "infill/ActualZigzagConnectorProcessor.h"
#include "infill/ZigzagConnectorProcessorNoEndPieces.h"
#include "infill/ZigzagConnectorProcessorEndPieces.h"
#include "infill/ZigzagConnectorProcessorConnectedEndPieces.h"
#include "infill/ZigzagConnectorProcessorDisconnectedEndPieces.h"
#include "utils/intpoint.h"
#include "utils/AABB.h"
namespace cura {
namespace cura
{
void generateConcentricInfill(Polygons outline, Polygons& result, int inset_value);
void generateAutomaticInfill(const Polygons& in_outline, Polygons& result, int extrusionWidth, int lineSpacing, int infillOverlap, double rotation);
void generateGridInfill(const Polygons& in_outline, Polygons& result, int extrusionWidth, int lineSpacing, int infillOverlap, double rotation);
void generateLineInfill(const Polygons& in_outline, Polygons& result, int extrusionWidth, int lineSpacing, int infillOverlap, double rotation);
class Infill
{
static constexpr int perimeter_gaps_extra_offset = 15; // extra offset so that the perimeter gaps aren't created everywhere due to rounding errors
EFillMethod pattern; //!< the space filling pattern of the infill to generate
const Polygons& in_outline; //!< a reference polygon for getting the actual area within which to generate infill (see outline_offset)
int outline_offset; //!< Offset from Infill::in_outline to get the actual area within which to generate infill
int infill_line_width; //!< The line width of the infill lines to generate
int line_distance; //!< The distance between two infill lines / polygons
int infill_overlap; //!< the distance by which to overlap with the actual area within which to generate infill
double fill_angle; //!< for linear infill types: the angle of the infill lines (or the angle of the grid)
int64_t z; //!< height of the layer for which we generate infill
int64_t shift; //!< shift of the scanlines in the direction perpendicular to the fill_angle
Polygons* perimeter_gaps; //!< (optional output) The areas in between consecutive insets when Concentric infill is used.
bool connected_zigzags; //!< (ZigZag) Whether endpieces of zigzag infill should be connected to the nearest infill line on both sides of the zigzag connector
bool use_endpieces; //!< (ZigZag) Whether to include endpieces: zigzag connector segments from one infill line to itself
static constexpr double one_over_sqrt_2 = 0.7071067811865475244008443621048490392848359376884740; //!< 1.0 / sqrt(2.0)
public:
/*!
* \warning If \p perimeter_gaps is given, then the difference between the \p in_outline
* and the polygons which result from offsetting it by the \p outline_offset
* and then expanding it again by half the \p infill_line_width
* is added to the \p perimeter_gaps
*
* \param[out] perimeter_gaps (optional output) The areas in between consecutive insets when Concentric infill is used.
*/
Infill(EFillMethod pattern
, const Polygons& in_outline
, int outline_offset
, int infill_line_width
, int line_distance
, int infill_overlap
, double fill_angle
, int64_t z
, int64_t shift
, Polygons* perimeter_gaps = nullptr
, bool connected_zigzags = false
, bool use_endpieces = false
)
: pattern(pattern)
, in_outline(in_outline)
, outline_offset(outline_offset)
, infill_line_width(infill_line_width)
, line_distance(line_distance)
, infill_overlap(infill_overlap)
, fill_angle(fill_angle)
, z(z)
, shift(shift)
, perimeter_gaps(perimeter_gaps)
, connected_zigzags(connected_zigzags)
, use_endpieces(use_endpieces)
{
}
/*!
* Generate the infill.
*
* \param result_polygons (output) The resulting polygons (from concentric infill)
* \param result_lines (output) The resulting line segments (from linear infill types)
*/
void generate(Polygons& result_polygons, Polygons& result_lines);
private:
/*!
* Function which returns the scanline_idx for a given x coordinate
*
* For negative \p x this is different from simple division.
*
* \warning \p line_distance is assumed to be positive
*
* \param x the point to get the scansegment index for
* \param line_distance the width of the scan segments
*/
static inline int computeScanSegmentIdx(int x, int line_distance);
/*!
* Generate sparse concentric infill
*
* Also adds \ref Inifll::perimeter_gaps between \ref Infill::in_outline and the first wall
*
* \param result (output) The resulting polygons
* \param inset_value The offset between each consecutive two polygons
*/
void generateConcentricInfill(Polygons& result, int inset_value);
/*!
* Generate sparse concentric infill starting from a specific outer wall
* \param first_wall The outer wall from which to start
* \param result (output) The resulting polygons
* \param inset_value The offset between each consecutive two polygons
*/
void generateConcentricInfill(Polygons& first_wall, Polygons& result, int inset_value);
/*!
* Generate sparse concentric infill
* \param result (output) The resulting polygons
*/
void generateConcentric3DInfill(Polygons& result);
/*!
* Generate a rectangular grid of infill lines
* \param result (output) The resulting lines
*/
void generateGridInfill(Polygons& result);
/*!
* Generate a shifting triangular grid of infill lines, which combine with consecutive layers into a cubic pattern
* \param result (output) The resulting lines
*/
void generateCubicInfill(Polygons& result);
/*!
* Generate a double shifting square grid of infill lines, which combine with consecutive layers into a tetrahedral pattern
* \param result (output) The resulting lines
*/
void generateTetrahedralInfill(Polygons& result);
/*!
* Generate a triangular grid of infill lines
* \param result (output) The resulting lines
*/
void generateTriangleInfill(Polygons& result);
/*!
* Convert a mapping from scanline to line_segment-scanline-intersections (\p cut_list) into line segments, using the even-odd rule
* \param result (output) The resulting lines
* \param rotation_matrix The rotation matrix (un)applied to enforce the angle of the infill
* \param scanline_min_idx The lowest index of all scanlines crossing the polygon
* \param line_distance The distance between two lines which are in the same direction
* \param boundary The axis aligned boundary box within which the polygon is
* \param cut_list A mapping of each scanline to all y-coordinates (in the space transformed by rotation_matrix) where the polygons are crossing the scanline
* \param total_shift total shift of the scanlines in the direction perpendicular to the fill_angle.
*/
void addLineInfill(Polygons& result, const PointMatrix& rotation_matrix, const int scanline_min_idx, const int line_distance, const AABB boundary, std::vector<std::vector<int64_t>>& cut_list, int64_t total_shift);
/*!
* generate lines within the area of \p in_outline, at regular intervals of \p line_distance
*
* idea:
* intersect a regular grid of 'scanlines' with the area inside \p in_outline
*
* \param result (output) The resulting lines
* \param line_distance The distance between two lines which are in the same direction
* \param fill_angle The angle of the generated lines
* \param extra_shift extra shift of the scanlines in the direction perpendicular to the fill_angle
*/
void generateLineInfill(Polygons& result, int line_distance, const double& fill_angle, int64_t extra_shift);
/*!
* Function for creating linear based infill types (Lines, ZigZag).
*
* This function implements the basic functionality of Infill::generateLineInfill (see doc of that function),
* but makes calls to a ZigzagConnectorProcessor which handles what to do with each line segment - scanline intersection.
*
* It is called only from Infill::generateLineinfill and Infill::generateZigZagInfill.
*
* \param outline_offset An offset from the reference polygon (Infill::in_outline) to get the actual outline within which to generate infill
* \param result (output) The resulting lines
* \param line_distance The distance between two lines which are in the same direction
* \param rotation_matrix The rotation matrix (un)applied to enforce the angle of the infill
* \param zigzag_connector_processor The processor used to generate zigzag connectors
* \param connected_zigzags Whether to connect the endpiece zigzag segments on both sides to the same infill line
* \param extra_shift extra shift of the scanlines in the direction perpendicular to the fill_angle
*/
void generateLinearBasedInfill(const int outline_offset, Polygons& result, const int line_distance, const PointMatrix& rotation_matrix, ZigzagConnectorProcessor& zigzag_connector_processor, const bool connected_zigzags, int64_t extra_shift);
/*!
*
* generate lines within the area of [in_outline], at regular intervals of [line_distance]
* idea:
* intersect a regular grid of 'scanlines' with the area inside [in_outline] (see generateLineInfill)
* zigzag:
* include pieces of boundary, connecting the lines, forming an accordion like zigzag instead of separate lines |_|^|_|
*
* Note that ZigZag consists of 3 types:
* - without endpieces
* - with disconnected endpieces
* - with connected endpieces
*
* <--
* ___
* | | |
* | | |
* | |___|
* -->
*
* ^ = even scanline
* ^ ^ no endpieces
*
* start boundary from even scanline! :D
*
*
* v disconnected end piece: leave out last line segment
* _____
* | | | \ .
* | | | |
* |_____| |__/
*
* ^ ^ ^ scanlines
*
*
* v connected end piece
* ________
* | | | \ .
* | | | |
* |_____| |__/ .
*
* ^ ^ ^ scanlines
*
* \param result (output) The resulting lines
* \param line_distance The distance between two lines which are in the same direction
* \param fill_angle The angle of the generated lines
* \param connected_zigzags Whether to connect the endpiece zigzag segments on both sides to the same infill line
* \param use_endpieces Whether to include zigzag segments connecting a scanline to itself
*/
void generateZigZagInfill(Polygons& result, const int line_distance, const double& fill_angle, const bool connected_zigzags, const bool use_endpieces);
};
}//namespace cura
+47
Ver Arquivo
@@ -0,0 +1,47 @@
/** Copyright (C) 2016 Ultimaker - Released under terms of the AGPLv3 License */
#ifndef INFILL_ACTUAL_ZIGZAG_CONNECTOR_PROCESSOR_H
#define INFILL_ACTUAL_ZIGZAG_CONNECTOR_PROCESSOR_H
#include "../utils/polygon.h"
#include "ZigzagConnectorProcessor.h"
#include "../utils/intpoint.h"
namespace cura
{
/*!
* In contrast to NoZigZagConnectorProcessor
*/
class ActualZigzagConnectorProcessor : public ZigzagConnectorProcessor
{
protected:
/*!
* The line segments belonging the zigzag connector to which the very first vertex belongs.
* This will be combined with the last handled zigzag_connector, which combine to a whole zigzag connector.
*
* Because the boundary polygon may start in in the middle of a zigzag connector,
*/
std::vector<Point> first_zigzag_connector;
/*!
* The currently built up zigzag connector (not the first/last) or end piece or discarded boundary segment
*/
std::vector<Point> zigzag_connector;
bool is_first_zigzag_connector; //!< Whether we're still in the first zigzag connector
bool first_zigzag_connector_ends_in_even_scanline; //!< Whether the first zigzag connector ends in an even scanline
bool last_scanline_is_even; //!< Whether the last seen scanline-boundary intersection was with an even scanline
ActualZigzagConnectorProcessor(const PointMatrix& rotation_matrix, Polygons& result)
: ZigzagConnectorProcessor(rotation_matrix, result)
, is_first_zigzag_connector(true)
, first_zigzag_connector_ends_in_even_scanline(true)
, last_scanline_is_even(false)
{
}
};
} // namespace cura
#endif // INFILL_ACTUAL_ZIGZAG_CONNECTOR_PROCESSOR_H
+25
Ver Arquivo
@@ -0,0 +1,25 @@
/** Copyright (C) 2016 Ultimaker - Released under terms of the AGPLv3 License */
#include "NoZigZagConnectorProcessor.h"
namespace cura
{
void NoZigZagConnectorProcessor::registerVertex(const Point& vertex)
{
}
void NoZigZagConnectorProcessor::registerScanlineSegmentIntersection(const Point& intersection, bool scanline_is_even)
{
}
void NoZigZagConnectorProcessor::registerPolyFinished()
{
}
} // namespace cura

Alguns arquivos não foram exibidos porque demasiados arquivos foram alterados neste diff Mostrar Mais